@tangle-network/agent-runtime 6.0.8 → 8.0.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 +86 -0
- package/README.md +23 -12
- package/dist/{activation-Cwy3_Qn_.js → activation-Ce4zUcu8.js} +4 -4
- package/dist/{activation-Cwy3_Qn_.js.map → activation-Ce4zUcu8.js.map} +1 -1
- package/dist/{activation-CWx7I1PU.d.ts → activation-xxvLF1-1.d.ts} +2 -2
- package/dist/agent.d.ts +1 -1
- package/dist/agent.js +3 -3
- package/dist/{bundle-Cy5igJdv.js → bundle-CcpL2lfr.js} +2 -2
- package/dist/{bundle-Cy5igJdv.js.map → bundle-CcpL2lfr.js.map} +1 -1
- package/dist/candidate-execution/index.js +4 -4
- package/dist/continuation-CIyKnS1Q.js +451 -0
- package/dist/continuation-CIyKnS1Q.js.map +1 -0
- package/dist/{coordination-manager-D9z7To7p.js → coordination-manager-sa_PkISw.js} +247 -149
- package/dist/coordination-manager-sa_PkISw.js.map +1 -0
- package/dist/{coordination-map-routing-CKRNZSaV.js → coordination-map-routing-XZXTlCmn.js} +2 -4
- package/dist/coordination-map-routing-XZXTlCmn.js.map +1 -0
- package/dist/{delegate-ws-KBA2H.js → delegate-DhTkJIta.js} +3 -3
- package/dist/{delegate-ws-KBA2H.js.map → delegate-DhTkJIta.js.map} +1 -1
- package/dist/durable.d.ts +71 -4
- package/dist/durable.js +162 -13
- package/dist/durable.js.map +1 -1
- package/dist/{errors-AzSuGI23.js → errors-DG8yufqX.js} +8 -1
- package/dist/errors-DG8yufqX.js.map +1 -0
- package/dist/{failure-cause-BzjUUsRz.js → failure-cause-CVB-YE88.js} +17 -16
- package/dist/failure-cause-CVB-YE88.js.map +1 -0
- package/dist/{graph-registry-7X2nrreR.js → graph-registry-czAwYwNj.js} +133 -9
- package/dist/graph-registry-czAwYwNj.js.map +1 -0
- package/dist/{graph-registry-gYbq4L5Z.js → graph-registry-uTIyyy7A.js} +1 -1
- package/dist/graph-tSIT_eWK.js +1793 -0
- package/dist/graph-tSIT_eWK.js.map +1 -0
- package/dist/{improve-BxfqTsZy.js → improve-H08hiIw9.js} +19 -48
- package/dist/improve-H08hiIw9.js.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +16 -16
- package/dist/intelligence.d.ts +2 -2
- package/dist/intelligence.js +8 -8
- package/dist/intelligence.js.map +1 -1
- package/dist/kernel.d.ts +2 -2
- package/dist/kernel.js +16 -15
- package/dist/{loop-runner-CUMypgRw.d.ts → loop-runner-BGwhcn1p.d.ts} +2 -2
- package/dist/{loop-runner-BmGZ4y1W.js → loop-runner-ChqK8kSz.js} +3 -3
- package/dist/{loop-runner-BmGZ4y1W.js.map → loop-runner-ChqK8kSz.js.map} +1 -1
- package/dist/loop-runner-bin.d.ts +1 -1
- package/dist/loop-runner-bin.js +1 -1
- package/dist/mcp/bin.js +7 -5
- package/dist/mcp/bin.js.map +1 -1
- package/dist/mcp/index.d.ts +1 -1
- package/dist/mcp/index.js +9 -9
- package/dist/mcp/memory-bin.js +2 -2
- package/dist/{model-policy-JOcg3NRs.js → model-policy-yxOrDTTj.js} +9 -9
- package/dist/model-policy-yxOrDTTj.js.map +1 -0
- package/dist/{prepare-Dtfk_Wi_.js → prepare-BnF8nGIg.js} +4 -4
- package/dist/{prepare-Dtfk_Wi_.js.map → prepare-BnF8nGIg.js.map} +1 -1
- package/dist/{profile-CNSQjOes.js → profile-CD25rTJF.js} +4 -4
- package/dist/{profile-CNSQjOes.js.map → profile-CD25rTJF.js.map} +1 -1
- package/dist/profiles.d.ts +1 -1
- package/dist/profiles.js +2 -2
- package/dist/{provision-supervisor-CeQTPHRr.js → provision-supervisor-Dx4TXTMM.js} +8 -8
- package/dist/{provision-supervisor-CeQTPHRr.js.map → provision-supervisor-Dx4TXTMM.js.map} +1 -1
- package/dist/{run-cancellation-D_4vJ522.js → run-cancellation-DYszFJtQ.js} +4 -4
- package/dist/{run-cancellation-D_4vJ522.js.map → run-cancellation-DYszFJtQ.js.map} +1 -1
- package/dist/{run-state-CTZVngI_.js → run-state-DHBoJjaF.js} +6 -6
- package/dist/{run-state-CTZVngI_.js.map → run-state-DHBoJjaF.js.map} +1 -1
- package/dist/{runtime-COm9uBBx.js → runtime-CaM5Gbbv.js} +76 -987
- package/dist/runtime-CaM5Gbbv.js.map +1 -0
- package/dist/{sandbox-profile-compat-oFGWESLn.js → sandbox-profile-compat-l-SLQnGb.js} +2 -2
- package/dist/{sandbox-profile-compat-oFGWESLn.js.map → sandbox-profile-compat-l-SLQnGb.js.map} +1 -1
- package/dist/{search-executor-DTEIl58w.js → search-executor-B9L8W_1O.js} +17 -46
- package/dist/search-executor-B9L8W_1O.js.map +1 -0
- package/dist/{server-zO9Nz9Nk.js → server-BlDV8sj_.js} +32 -8
- package/dist/{server-zO9Nz9Nk.js.map → server-BlDV8sj_.js.map} +1 -1
- package/dist/{settle-record-U7fkQEZa.js → settle-record-WWQasnDq.js} +12 -4
- package/dist/settle-record-WWQasnDq.js.map +1 -0
- package/dist/{snapshot-Cgj2Wzi6.js → snapshot-BKI_w3JD.js} +19 -5
- package/dist/snapshot-BKI_w3JD.js.map +1 -0
- package/dist/{structural-rollout-BwTwTUXF.js → structural-rollout-C1xxoWcN.js} +39 -57
- package/dist/structural-rollout-C1xxoWcN.js.map +1 -0
- package/dist/{supervise-tmqDU6YT.js → supervise-DWiSgPLB.js} +103 -111
- package/dist/supervise-DWiSgPLB.js.map +1 -0
- package/dist/{supervision-discovery-CGbXayGv.js → supervision-discovery-C9kfBLKy.js} +4 -4
- package/dist/{supervision-discovery-CGbXayGv.js.map → supervision-discovery-C9kfBLKy.js.map} +1 -1
- package/dist/{supervisor-1A27fE6k.js → supervisor-Dpeu7rnZ.js} +209 -999
- package/dist/supervisor-Dpeu7rnZ.js.map +1 -0
- package/dist/{scope-gIYQ5ZiL.js → supervisor-accounting-Bw4MJk-b.js} +755 -458
- package/dist/supervisor-accounting-Bw4MJk-b.js.map +1 -0
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +13 -13
- package/dist/{tool-server-B9q2dtnW.js → tool-server-DYwRbi0I.js} +3 -3
- package/dist/{tool-server-B9q2dtnW.js.map → tool-server-DYwRbi0I.js.map} +1 -1
- package/dist/{top-web-CS4PD4ck.js → top-web-B3HOAtrZ.js} +9 -7
- package/dist/{top-web-CS4PD4ck.js.map → top-web-B3HOAtrZ.js.map} +1 -1
- package/dist/tui/bin.js +6 -6
- package/dist/tui/bin.js.map +1 -1
- package/dist/tui/index.d.ts +1 -1
- package/dist/tui/index.js +2 -2
- package/dist/{types-w3Oo1uRJ.d.ts → types-C_qbnw9N.d.ts} +1263 -1497
- package/dist/{util-C_cdPNC4.js → util-fcckrkKp.js} +39 -113
- package/dist/util-fcckrkKp.js.map +1 -0
- package/dist/{workspace-streams-B7yNMahl.js → workspace-streams-DA9R3j-p.js} +2 -2
- package/dist/{workspace-streams-B7yNMahl.js.map → workspace-streams-DA9R3j-p.js.map} +1 -1
- package/package.json +1 -1
- package/dist/coordination-manager-D9z7To7p.js.map +0 -1
- package/dist/coordination-map-routing-CKRNZSaV.js.map +0 -1
- package/dist/errors-AzSuGI23.js.map +0 -1
- package/dist/failure-cause-BzjUUsRz.js.map +0 -1
- package/dist/graph-2_nX4ib4.js +0 -579
- package/dist/graph-2_nX4ib4.js.map +0 -1
- package/dist/graph-registry-7X2nrreR.js.map +0 -1
- package/dist/improve-BxfqTsZy.js.map +0 -1
- package/dist/model-policy-JOcg3NRs.js.map +0 -1
- package/dist/runtime-COm9uBBx.js.map +0 -1
- package/dist/scope-gIYQ5ZiL.js.map +0 -1
- package/dist/search-executor-DTEIl58w.js.map +0 -1
- package/dist/settle-record-U7fkQEZa.js.map +0 -1
- package/dist/snapshot-Cgj2Wzi6.js.map +0 -1
- package/dist/structural-rollout-BwTwTUXF.js.map +0 -1
- package/dist/supervise-tmqDU6YT.js.map +0 -1
- package/dist/supervisor-1A27fE6k.js.map +0 -1
- package/dist/util-C_cdPNC4.js.map +0 -1
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
import { m as ValidationError } from "./errors-DG8yufqX.js";
|
|
2
|
+
import { l as sha256 } from "./jsonl-file-DsxVI0E_.js";
|
|
3
|
+
import { a as writeAtomicDurableFile } from "./durable-file-DstVeHcj.js";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { mkdir } from "node:fs/promises";
|
|
6
|
+
// src/finite-number.ts
|
|
7
|
+
function isFiniteNumber(value) {
|
|
8
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
9
|
+
}
|
|
10
|
+
// src/runtime/supervise/continuation.ts
|
|
11
|
+
/**
|
|
12
|
+
* One check ({@link CheckVerdict}; {@link CheckUnavailableError} pauses), one
|
|
13
|
+
* {@link ContinuationPolicy} (`maxBarren`, an optional deadline, no re-prompt default), and one
|
|
14
|
+
* note ({@link composeContinuationNote} owns the facts, {@link ContinuationProfile} owns the
|
|
15
|
+
* words, a play may only append).
|
|
16
|
+
*/
|
|
17
|
+
/** Read a check function's return value into a verdict. Anything but `true` or a passing verdict
|
|
18
|
+
* is a failure: a check fails closed. */
|
|
19
|
+
function checkVerdictOf(outcome) {
|
|
20
|
+
if (outcome === true) return { pass: true };
|
|
21
|
+
if (typeof outcome !== "object" || outcome === null || Array.isArray(outcome)) return { pass: false };
|
|
22
|
+
const raw = outcome;
|
|
23
|
+
const items = typeof raw.items === "object" && raw.items !== null && !Array.isArray(raw.items) ? Object.fromEntries(Object.entries(raw.items).filter((entry) => typeof entry[1] === "number" && Number.isFinite(entry[1]))) : void 0;
|
|
24
|
+
const failures = Array.isArray(raw.failures) ? raw.failures.filter((line) => typeof line === "string" && line.trim() !== "") : void 0;
|
|
25
|
+
return Object.freeze({
|
|
26
|
+
pass: raw.pass === true,
|
|
27
|
+
...items === void 0 ? {} : { items: Object.freeze(items) },
|
|
28
|
+
...isFiniteNumber(raw.composite) ? { composite: raw.composite } : {},
|
|
29
|
+
...isFiniteNumber(raw.threshold) ? { threshold: raw.threshold } : {},
|
|
30
|
+
...failures === void 0 ? {} : { failures: Object.freeze(failures) },
|
|
31
|
+
...typeof raw.review === "string" && raw.review.trim() !== "" ? { review: raw.review.trim() } : {}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
/** Items that fail in `verdict`: every item below 1, or the named items of its FAIL lines. */
|
|
35
|
+
function failedItems(verdict) {
|
|
36
|
+
if (verdict.items !== void 0) return Object.entries(verdict.items).filter(([, value]) => value < 1).map(([name]) => name);
|
|
37
|
+
return (verdict.failures ?? []).map((line) => line.slice(5).split(/[\s:]/u)[0] ?? "");
|
|
38
|
+
}
|
|
39
|
+
/** Items that pass in `verdict`. */
|
|
40
|
+
function passedItems(verdict) {
|
|
41
|
+
return Object.entries(verdict.items ?? {}).filter(([, value]) => value >= 1).map(([name]) => name);
|
|
42
|
+
}
|
|
43
|
+
/** Resolve and check a policy before any compute. Returns the deadline in epoch ms, or undefined
|
|
44
|
+
* when the policy sets none. */
|
|
45
|
+
function admitContinuationPolicy(policy, context) {
|
|
46
|
+
if (typeof policy !== "object" || policy === null) throw new ValidationError(`${context}: continuation must be an object`);
|
|
47
|
+
const deadlineMs = typeof policy.deadline === "string" ? Date.parse(policy.deadline) : policy.deadline;
|
|
48
|
+
if (deadlineMs !== void 0 && (typeof deadlineMs !== "number" || !Number.isFinite(deadlineMs) || deadlineMs <= 0)) throw new ValidationError(`${context}: continuation.deadline, when set, must be a finite time (epoch ms or ISO 8601)`);
|
|
49
|
+
if (!Number.isInteger(policy.maxBarren) || policy.maxBarren < 1) throw new ValidationError(`${context}: continuation.maxBarren must be an integer >= 1`);
|
|
50
|
+
if (policy.failures !== "verbatim" && policy.failures !== "off") throw new ValidationError(`${context}: continuation.failures must be 'verbatim' or 'off'`);
|
|
51
|
+
if (policy.panel !== "on" && policy.panel !== "off") throw new ValidationError(`${context}: continuation.panel must be 'on' or 'off'`);
|
|
52
|
+
if (policy.bar !== "on" && policy.bar !== "off") throw new ValidationError(`${context}: continuation.bar must be 'on' or 'off'`);
|
|
53
|
+
if (policy.panel === "on") {
|
|
54
|
+
if (typeof policy.runPanel !== "function") throw new ValidationError(`${context}: continuation.panel 'on' needs runPanel`);
|
|
55
|
+
const usd = policy.panelUsd;
|
|
56
|
+
if (usd === void 0 || !isFiniteNumber(usd.perContinuation) || !isFiniteNumber(usd.perRun) || usd.perContinuation <= 0 || usd.perRun < usd.perContinuation) throw new ValidationError(`${context}: continuation.panel 'on' needs panelUsd with 0 < perContinuation <= perRun`);
|
|
57
|
+
}
|
|
58
|
+
if (policy.append !== void 0 && typeof policy.append !== "function") throw new ValidationError(`${context}: continuation.append must be a function`);
|
|
59
|
+
if (policy.session !== void 0 && policy.session !== "native" && policy.session !== "fresh") throw new ValidationError(`${context}: continuation.session must be 'native' or 'fresh'`);
|
|
60
|
+
if (policy.reference !== void 0 && typeof policy.reference !== "string") throw new ValidationError(`${context}: continuation.reference must be a string`);
|
|
61
|
+
admitContinuationProfile(policy.profile, context);
|
|
62
|
+
return deadlineMs;
|
|
63
|
+
}
|
|
64
|
+
/** The facts a profile template may name. */
|
|
65
|
+
const CONTINUATION_FACTS = [
|
|
66
|
+
"composite",
|
|
67
|
+
"threshold",
|
|
68
|
+
"failed",
|
|
69
|
+
"total",
|
|
70
|
+
"reads",
|
|
71
|
+
"owed",
|
|
72
|
+
"settled",
|
|
73
|
+
"delivered",
|
|
74
|
+
"continuation"
|
|
75
|
+
];
|
|
76
|
+
const factNames = new Set(CONTINUATION_FACTS);
|
|
77
|
+
const placeholder = /\{([a-zA-Z]+)\}/gu;
|
|
78
|
+
function admitContinuationProfile(profile, context) {
|
|
79
|
+
if (typeof profile !== "object" || profile === null) throw new ValidationError(`${context}: continuation.profile must be an object`);
|
|
80
|
+
if (typeof profile.id !== "string" || profile.id.trim() === "") throw new ValidationError(`${context}: continuation.profile.id must be non-empty`);
|
|
81
|
+
const texts = [
|
|
82
|
+
["opening", profile.opening],
|
|
83
|
+
["plan", profile.plan],
|
|
84
|
+
["rules", profile.rules],
|
|
85
|
+
...Object.entries(profile.headings ?? {}).map(([key, value]) => [`headings.${key}`, value]),
|
|
86
|
+
...profile.barRule === void 0 ? [] : [["barRule", profile.barRule]]
|
|
87
|
+
];
|
|
88
|
+
for (const key of [
|
|
89
|
+
"failures",
|
|
90
|
+
"protected",
|
|
91
|
+
"changed",
|
|
92
|
+
"findings",
|
|
93
|
+
"bar",
|
|
94
|
+
"plan",
|
|
95
|
+
"rules"
|
|
96
|
+
]) if (typeof profile.headings?.[key] !== "string") throw new ValidationError(`${context}: continuation.profile.headings.${key} must be a string`);
|
|
97
|
+
for (const [key, text] of texts) {
|
|
98
|
+
if (typeof text !== "string") throw new ValidationError(`${context}: continuation.profile.${key} must be a string`);
|
|
99
|
+
for (const match of text.matchAll(placeholder)) if (!factNames.has(match[1] ?? "")) throw new ValidationError(`${context}: continuation.profile.${key} names {${match[1]}}, which is not a fact Runtime supplies (${CONTINUATION_FACTS.join(", ")})`);
|
|
100
|
+
}
|
|
101
|
+
if (profile.review !== void 0) {
|
|
102
|
+
if (typeof profile.review !== "string" || profile.review.trim() === "") throw new ValidationError(`${context}: continuation.profile.review must be non-empty`);
|
|
103
|
+
for (const match of profile.review.matchAll(placeholder)) if (![
|
|
104
|
+
"version",
|
|
105
|
+
"path",
|
|
106
|
+
"score"
|
|
107
|
+
].includes(match[1] ?? "")) throw new ValidationError(`${context}: continuation.profile.review names {${match[1]}}; it may name {version}, {path} and {score}`);
|
|
108
|
+
}
|
|
109
|
+
if (profile.opening.trim() === "") throw new ValidationError(`${context}: continuation.profile.opening must be non-empty`);
|
|
110
|
+
if (profile.panelModel !== void 0 && typeof profile.panelModel !== "string") throw new ValidationError(`${context}: continuation.profile.panelModel must be a string`);
|
|
111
|
+
if (profile.questions !== void 0 && !Array.isArray(profile.questions)) throw new ValidationError(`${context}: continuation.profile.questions must be an array`);
|
|
112
|
+
for (const [index, question] of (profile.questions ?? []).entries()) if (typeof question !== "string" || question.trim() === "") throw new ValidationError(`${context}: continuation.profile.questions[${index}] must be a non-empty string`);
|
|
113
|
+
}
|
|
114
|
+
/** Findings reach the note only when every citation resolves, at least two distinct spans are
|
|
115
|
+
* cited, and the independent verifier agreed. The best method in Who&When found the failing step
|
|
116
|
+
* 14.2% of the time, so an unverified finding is noise with a citation. */
|
|
117
|
+
function admitFinding(finding) {
|
|
118
|
+
if (!finding.verified) return false;
|
|
119
|
+
if (finding.citations.length === 0) return false;
|
|
120
|
+
if (!finding.citations.every((citation) => citation.resolved)) return false;
|
|
121
|
+
return new Set(finding.citations.map((citation) => citation.uri)).size >= 2;
|
|
122
|
+
}
|
|
123
|
+
/** About 1,500 tokens of findings. */
|
|
124
|
+
const FINDINGS_CHAR_CAP = 6e3;
|
|
125
|
+
/**
|
|
126
|
+
* Rank the admitted findings by how many failed items they explain, drop repeats, and keep them
|
|
127
|
+
* within the note's cap. Earlier findings stay as they were written (ACE: itemized additions keep
|
|
128
|
+
* detail that repeated rewrites lose); a finding whose items all pass now is marked resolved.
|
|
129
|
+
*/
|
|
130
|
+
function distillFindings(prior, proposed, failing, continuation) {
|
|
131
|
+
const key = (claim) => claim.toLowerCase().replace(/\s+/gu, " ").trim();
|
|
132
|
+
const known = new Set(prior.map((finding) => key(finding.claim)));
|
|
133
|
+
const carried = prior.map((finding) => finding.resolvedAt === void 0 && (finding.items?.length ?? 0) > 0 && (finding.items ?? []).every((item) => !failing.has(item)) ? {
|
|
134
|
+
...finding,
|
|
135
|
+
resolvedAt: continuation
|
|
136
|
+
} : finding);
|
|
137
|
+
const fresh = proposed.filter(admitFinding).filter((finding) => {
|
|
138
|
+
const k = key(finding.claim);
|
|
139
|
+
if (known.has(k)) return false;
|
|
140
|
+
known.add(k);
|
|
141
|
+
return true;
|
|
142
|
+
}).map((finding) => ({
|
|
143
|
+
finding,
|
|
144
|
+
links: (finding.items ?? []).filter((item) => failing.has(item)).length
|
|
145
|
+
})).sort((a, b) => b.links - a.links);
|
|
146
|
+
const out = [...carried];
|
|
147
|
+
let used = carried.filter((finding) => finding.resolvedAt === void 0).reduce((sum, finding) => sum + finding.claim.length, 0);
|
|
148
|
+
for (const { finding } of fresh) {
|
|
149
|
+
if (used + finding.claim.length > FINDINGS_CHAR_CAP) break;
|
|
150
|
+
used += finding.claim.length;
|
|
151
|
+
out.push({
|
|
152
|
+
...finding,
|
|
153
|
+
admittedAt: continuation
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
return out;
|
|
157
|
+
}
|
|
158
|
+
/** Expand the profile's question templates over the failed items and the settled workers. */
|
|
159
|
+
function expandQuestions(templates, failing, workers) {
|
|
160
|
+
const out = [];
|
|
161
|
+
for (const template of templates) {
|
|
162
|
+
const hasItem = template.includes("{item}");
|
|
163
|
+
const hasWorker = template.includes("{worker}");
|
|
164
|
+
if (!hasItem && !hasWorker) {
|
|
165
|
+
out.push(template);
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
const items = hasItem ? failing : [""];
|
|
169
|
+
const each = hasWorker ? workers.map((worker) => `${worker.id} (${worker.label})`) : [""];
|
|
170
|
+
for (const item of items) for (const worker of each) out.push(template.replaceAll("{item}", item).replaceAll("{worker}", worker));
|
|
171
|
+
}
|
|
172
|
+
return out;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Write one continuation note, sections 1 to 8 of docs/38. Section 9, the run's state, is
|
|
176
|
+
* `composeReentryTask`, which wraps this text. Pure: the same input writes the same note.
|
|
177
|
+
*/
|
|
178
|
+
function composeContinuationNote(input) {
|
|
179
|
+
const { profile, verdict } = input;
|
|
180
|
+
const items = verdict?.items ?? {};
|
|
181
|
+
const total = Object.keys(items).length;
|
|
182
|
+
const failing = verdict === void 0 ? [] : failedItems(verdict);
|
|
183
|
+
const facts = {
|
|
184
|
+
composite: verdict?.composite === void 0 ? "unknown" : format(verdict.composite),
|
|
185
|
+
threshold: verdict?.threshold === void 0 ? "unknown" : format(verdict.threshold),
|
|
186
|
+
failed: verdict === void 0 || total === 0 && (verdict.failures?.length ?? 0) === 0 ? "unknown" : String(failing.length),
|
|
187
|
+
total: total === 0 ? "unknown" : String(total),
|
|
188
|
+
reads: String(input.reads),
|
|
189
|
+
owed: input.owed?.trim() || "not described",
|
|
190
|
+
settled: String(input.progress.settledCount),
|
|
191
|
+
delivered: String(input.progress.deliveredCount ?? 0),
|
|
192
|
+
continuation: String(input.continuation)
|
|
193
|
+
};
|
|
194
|
+
const fill = (text) => text.replace(placeholder, (_, name) => facts[name] ?? `{${name}}`);
|
|
195
|
+
const sections = [verdict === void 0 ? "No check verdict is available yet." + (input.canSubmitResult === true ? " Submit a result through submit_result to request the check." : "") : verdict.pass ? "The check passes on the current state, but no result has been accepted." + (input.canSubmitResult === true ? " Call submit_result to request acceptance." : "") : fill(profile.opening).trim()];
|
|
196
|
+
const section = (heading, body) => {
|
|
197
|
+
if (body.length === 0) return;
|
|
198
|
+
sections.push([...heading.trim() === "" ? [] : [`## ${fill(heading)}`], ...body].join("\n"));
|
|
199
|
+
};
|
|
200
|
+
if (input.failures === "verbatim" && verdict !== void 0) {
|
|
201
|
+
const lines = verdict.failures ?? [];
|
|
202
|
+
const shown = lines.slice(0, 40);
|
|
203
|
+
const more = lines.length - shown.length;
|
|
204
|
+
section(profile.headings.failures, [...shown, ...more > 0 ? [input.canReadMore ? `${more} more failure lines: call read_continuation with continuation ${input.continuation}.` : `${more} more failure lines are not shown.`] : []]);
|
|
205
|
+
const passing = passedItems(verdict);
|
|
206
|
+
section(profile.headings.protected, passing.length === 0 ? [] : [passing.join(", ")]);
|
|
207
|
+
if (input.previous !== void 0) {
|
|
208
|
+
const before = new Set(failedItems(input.previous));
|
|
209
|
+
const now = new Set(failing);
|
|
210
|
+
const fixed = [...before].filter((item) => !now.has(item));
|
|
211
|
+
const broke = [...now].filter((item) => !before.has(item));
|
|
212
|
+
section(profile.headings.changed, [
|
|
213
|
+
...fixed.length === 0 ? [] : [`Now passing: ${fixed.join(", ")}.`],
|
|
214
|
+
...broke.length === 0 ? [] : [`Newly failing: ${broke.join(", ")}.`],
|
|
215
|
+
...fixed.length === 0 && broke.length === 0 ? ["No item changed since the last note."] : [],
|
|
216
|
+
...input.previous.composite !== void 0 && verdict.composite !== void 0 ? [`Composite: ${format(input.previous.composite)} then ${format(verdict.composite)}.`] : []
|
|
217
|
+
]);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
if (input.findings !== void 0) {
|
|
221
|
+
const open = input.findings.filter((finding) => finding.resolvedAt === void 0);
|
|
222
|
+
const resolved = input.findings.filter((finding) => finding.resolvedAt === input.continuation);
|
|
223
|
+
section(profile.headings.findings, [...open.map((finding) => `- [hypothesis] ${finding.claim}` + (finding.items?.length ? ` (items: ${finding.items.join(", ")})` : "") + ` Evidence: ${finding.citations.map((citation) => citation.uri).join(", ")}`), ...resolved.map((finding) => `- [resolved] ${finding.claim}`)]);
|
|
224
|
+
}
|
|
225
|
+
if (input.bar !== void 0 && verdict !== void 0) {
|
|
226
|
+
const body = [];
|
|
227
|
+
if (profile.barRule?.trim()) body.push(fill(profile.barRule).trim());
|
|
228
|
+
for (const [item, value] of Object.entries(items)) {
|
|
229
|
+
const best = input.bar.best?.verdict.items?.[item];
|
|
230
|
+
body.push(`- ${item}: ${value >= 1 ? "passes" : `fails (${format(value)})`}` + (best === void 0 ? "" : ` / ${input.bar.best?.label}: ${best >= 1 ? "passes" : `fails (${format(best)})`}`));
|
|
231
|
+
}
|
|
232
|
+
if (input.bar.best?.verdict.composite !== void 0) body.push(`Best version ${input.bar.best.label}: composite ${format(input.bar.best.verdict.composite)}.`);
|
|
233
|
+
if (input.bar.reference?.trim()) body.push(`Reference result: ${input.bar.reference.trim()}`);
|
|
234
|
+
if (verdict.review?.trim()) body.push(`The check's review: ${verdict.review.trim()}`);
|
|
235
|
+
section(profile.headings.bar, body);
|
|
236
|
+
}
|
|
237
|
+
section(profile.headings.plan, profile.plan.trim() === "" ? [] : [fill(profile.plan).trim()]);
|
|
238
|
+
section(profile.headings.rules, [...profile.rules.trim() === "" ? [] : [fill(profile.rules).trim()], ...input.sealed ? ["The score comes from cases you cannot see."] : []]);
|
|
239
|
+
for (const appended of input.appended ?? []) section(appended.heading, appended.text.trim() === "" ? [] : [appended.text.trim()]);
|
|
240
|
+
return sections.join("\n\n");
|
|
241
|
+
}
|
|
242
|
+
function summarizeVerdict(verdict) {
|
|
243
|
+
if (verdict === void 0) return null;
|
|
244
|
+
const total = Object.keys(verdict.items ?? {}).length;
|
|
245
|
+
return {
|
|
246
|
+
pass: verdict.pass,
|
|
247
|
+
...verdict.composite === void 0 ? {} : { composite: verdict.composite },
|
|
248
|
+
...total === 0 ? {} : {
|
|
249
|
+
failed: failedItems(verdict).length,
|
|
250
|
+
total
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
function noteDigest(note) {
|
|
255
|
+
return `sha256:${sha256(note)}`;
|
|
256
|
+
}
|
|
257
|
+
/** A run directory's continuation files: the root's at `<runDir>/continuations/<n>/`, a nested
|
|
258
|
+
* manager's at `<runDir>/continuations/managers/<owner>/<n>/`. */
|
|
259
|
+
const CONTINUATIONS_DIR = "continuations";
|
|
260
|
+
/**
|
|
261
|
+
* Write one continuation's files under `<dir>/<n>/`: `note.md`, `verdict.json`, and
|
|
262
|
+
* `panel.jsonl` when the panel ran. The director reads them through `read_continuation`, because
|
|
263
|
+
* its box cannot read the driver's run directory.
|
|
264
|
+
*/
|
|
265
|
+
async function writeContinuationFiles(dir, continuation, files) {
|
|
266
|
+
const at = join(dir, String(continuation));
|
|
267
|
+
await mkdir(at, { recursive: true });
|
|
268
|
+
writeAtomicDurableFile(join(at, "note.md"), `${files.note}\n`);
|
|
269
|
+
writeAtomicDurableFile(join(at, "verdict.json"), `${JSON.stringify(files.verdict ?? null, null, 2)}\n`);
|
|
270
|
+
if (files.panel !== void 0) writeAtomicDurableFile(join(at, "panel.jsonl"), files.panel.map((line) => JSON.stringify(line)).join("\n") + (files.panel.length ? "\n" : ""));
|
|
271
|
+
}
|
|
272
|
+
/** The best composite across `reads`, or `undefined` when no read scored. */
|
|
273
|
+
function bestComposite(reads) {
|
|
274
|
+
let best;
|
|
275
|
+
for (const read of reads) {
|
|
276
|
+
const value = read.verdict?.composite;
|
|
277
|
+
if (value !== void 0 && (best === void 0 || value > best)) best = value;
|
|
278
|
+
}
|
|
279
|
+
return best;
|
|
280
|
+
}
|
|
281
|
+
function format(value) {
|
|
282
|
+
return Number.isInteger(value) ? String(value) : value.toFixed(3).replace(/0+$/u, "");
|
|
283
|
+
}
|
|
284
|
+
/** Build the continuation state for one manager with a check. */
|
|
285
|
+
function createContinuationKeeper(input) {
|
|
286
|
+
const { policy } = input;
|
|
287
|
+
const failures = input.feedback === "pass-only" ? "off" : policy.failures;
|
|
288
|
+
const entries = [];
|
|
289
|
+
const notes = [];
|
|
290
|
+
let findings = [];
|
|
291
|
+
let panelUsd = 0;
|
|
292
|
+
let panelUsdKnown = true;
|
|
293
|
+
const latestVerdict = () => {
|
|
294
|
+
const reads = input.reads();
|
|
295
|
+
for (let i = reads.length - 1; i >= 0; i -= 1) {
|
|
296
|
+
const read = reads[i];
|
|
297
|
+
if (read?.verdict !== void 0) return {
|
|
298
|
+
verdict: read.verdict,
|
|
299
|
+
read: read.read
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
return { read: 0 };
|
|
303
|
+
};
|
|
304
|
+
const closePrevious = () => {
|
|
305
|
+
const last = entries.at(-1);
|
|
306
|
+
const lastNote = notes.at(-1);
|
|
307
|
+
if (last === void 0 || lastNote === void 0) return;
|
|
308
|
+
const latest = latestVerdict();
|
|
309
|
+
entries[entries.length - 1] = {
|
|
310
|
+
...last,
|
|
311
|
+
after: latest.read > lastNote.read ? summarizeVerdict(latest.verdict) : null
|
|
312
|
+
};
|
|
313
|
+
};
|
|
314
|
+
return {
|
|
315
|
+
async compose(context) {
|
|
316
|
+
closePrevious();
|
|
317
|
+
const continuation = entries.length + 1;
|
|
318
|
+
const { verdict, read } = latestVerdict();
|
|
319
|
+
const failing = verdict === void 0 ? [] : failedItems(verdict);
|
|
320
|
+
let panelRecord;
|
|
321
|
+
let panelLines;
|
|
322
|
+
if (policy.panel === "on" && policy.runPanel !== void 0 && policy.panelUsd !== void 0) {
|
|
323
|
+
const workers = input.workers();
|
|
324
|
+
const questions = expandQuestions(policy.profile.questions ?? [], failing, workers);
|
|
325
|
+
const left = policy.panelUsd.perRun - panelUsd;
|
|
326
|
+
const usdCap = Math.min(policy.panelUsd.perContinuation, left);
|
|
327
|
+
const asking = questions.length > 0 && usdCap > 0 && panelUsdKnown;
|
|
328
|
+
let traces;
|
|
329
|
+
let unavailable;
|
|
330
|
+
if (asking) try {
|
|
331
|
+
traces = await input.traces?.();
|
|
332
|
+
if (traces === void 0) unavailable = "the run has recorded no trace yet";
|
|
333
|
+
} catch (error) {
|
|
334
|
+
unavailable = `the run's traces could not be read: ${error instanceof Error ? error.message : String(error)}`;
|
|
335
|
+
}
|
|
336
|
+
if (asking && traces !== void 0) {
|
|
337
|
+
const result = await policy.runPanel({
|
|
338
|
+
continuation,
|
|
339
|
+
task: input.task,
|
|
340
|
+
...verdict === void 0 ? {} : { verdict },
|
|
341
|
+
reads: input.reads(),
|
|
342
|
+
questions,
|
|
343
|
+
traces,
|
|
344
|
+
workers,
|
|
345
|
+
...policy.best === void 0 ? {} : { bar: policy.best },
|
|
346
|
+
...policy.reference === void 0 ? {} : { reference: policy.reference },
|
|
347
|
+
usdCap,
|
|
348
|
+
signal: context.signal
|
|
349
|
+
});
|
|
350
|
+
if (result.usd === null) panelUsdKnown = false;
|
|
351
|
+
else panelUsd += result.usd;
|
|
352
|
+
findings = distillFindings(findings, result.findings, new Set(failing), continuation);
|
|
353
|
+
panelRecord = {
|
|
354
|
+
asked: questions.length,
|
|
355
|
+
proposed: result.findings.length,
|
|
356
|
+
admitted: findings.filter((finding) => finding.admittedAt === continuation).length,
|
|
357
|
+
usd: result.usd
|
|
358
|
+
};
|
|
359
|
+
panelLines = [...result.findings.map((finding) => ({
|
|
360
|
+
kind: "finding",
|
|
361
|
+
admitted: admitFinding(finding),
|
|
362
|
+
...finding
|
|
363
|
+
})), ...result.receipts === void 0 ? [] : [{
|
|
364
|
+
kind: "receipts",
|
|
365
|
+
receipts: result.receipts
|
|
366
|
+
}]];
|
|
367
|
+
} else panelRecord = {
|
|
368
|
+
asked: 0,
|
|
369
|
+
proposed: 0,
|
|
370
|
+
admitted: 0,
|
|
371
|
+
usd: 0,
|
|
372
|
+
...unavailable === void 0 ? {} : { unavailable }
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
const appended = policy.append ? await policy.append({
|
|
376
|
+
continuation,
|
|
377
|
+
...verdict === void 0 ? {} : { verdict },
|
|
378
|
+
reads: input.reads(),
|
|
379
|
+
signal: context.signal
|
|
380
|
+
}) : void 0;
|
|
381
|
+
const note = composeContinuationNote({
|
|
382
|
+
profile: policy.profile,
|
|
383
|
+
continuation,
|
|
384
|
+
...verdict === void 0 ? {} : { verdict },
|
|
385
|
+
...notes.at(-1)?.verdict === void 0 ? {} : { previous: notes.at(-1)?.verdict },
|
|
386
|
+
reads: input.reads().length,
|
|
387
|
+
failures,
|
|
388
|
+
...policy.panel === "on" ? { findings } : {},
|
|
389
|
+
...policy.bar === "on" ? { bar: {
|
|
390
|
+
...policy.best === void 0 ? {} : { best: policy.best },
|
|
391
|
+
...policy.reference === void 0 ? {} : { reference: policy.reference }
|
|
392
|
+
} } : {},
|
|
393
|
+
...appended === void 0 ? {} : { appended: [appended] },
|
|
394
|
+
...input.owed === void 0 ? {} : { owed: input.owed },
|
|
395
|
+
progress: context.progress,
|
|
396
|
+
canReadMore: input.canReadMore,
|
|
397
|
+
canSubmitResult: input.canSubmitResult === true,
|
|
398
|
+
...input.sealed === true ? { sealed: true } : {}
|
|
399
|
+
});
|
|
400
|
+
notes.push({
|
|
401
|
+
note,
|
|
402
|
+
...verdict === void 0 ? {} : { verdict },
|
|
403
|
+
...panelLines === void 0 ? {} : { panel: panelLines },
|
|
404
|
+
read
|
|
405
|
+
});
|
|
406
|
+
entries.push({
|
|
407
|
+
continuation,
|
|
408
|
+
attempt: context.attempt,
|
|
409
|
+
noteDigest: noteDigest(note),
|
|
410
|
+
profile: policy.profile.id,
|
|
411
|
+
switches: {
|
|
412
|
+
failures,
|
|
413
|
+
panel: policy.panel,
|
|
414
|
+
bar: policy.bar
|
|
415
|
+
},
|
|
416
|
+
before: summarizeVerdict(verdict),
|
|
417
|
+
after: null,
|
|
418
|
+
...panelRecord === void 0 ? {} : { panel: panelRecord },
|
|
419
|
+
appended: appended === void 0 ? 0 : 1
|
|
420
|
+
});
|
|
421
|
+
if (input.dir !== void 0) await writeContinuationFiles(input.dir, continuation, {
|
|
422
|
+
note,
|
|
423
|
+
...verdict === void 0 ? {} : { verdict },
|
|
424
|
+
...panelLines === void 0 ? {} : { panel: panelLines }
|
|
425
|
+
});
|
|
426
|
+
return note;
|
|
427
|
+
},
|
|
428
|
+
read(continuation) {
|
|
429
|
+
const index = continuation === void 0 ? notes.length - 1 : continuation - 1;
|
|
430
|
+
const entry = notes[index];
|
|
431
|
+
if (entry === void 0) return {
|
|
432
|
+
found: false,
|
|
433
|
+
reason: notes.length === 0 ? "no continuation has been sent in this run" : `continuations run from 1 to ${notes.length}`
|
|
434
|
+
};
|
|
435
|
+
return {
|
|
436
|
+
found: true,
|
|
437
|
+
continuation: index + 1,
|
|
438
|
+
note: entry.note,
|
|
439
|
+
verdict: failures === "off" && entry.verdict !== void 0 ? { pass: entry.verdict.pass } : entry.verdict ?? null,
|
|
440
|
+
findings: findings.filter((finding) => finding.admittedAt <= index + 1)
|
|
441
|
+
};
|
|
442
|
+
},
|
|
443
|
+
entries() {
|
|
444
|
+
closePrevious();
|
|
445
|
+
return entries.map((entry) => ({ ...entry }));
|
|
446
|
+
}
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
export { createContinuationKeeper as a, checkVerdictOf as i, admitContinuationPolicy as n, failedItems as o, bestComposite as r, isFiniteNumber as s, CONTINUATIONS_DIR as t };
|
|
450
|
+
|
|
451
|
+
//# sourceMappingURL=continuation-CIyKnS1Q.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"continuation-CIyKnS1Q.js","names":[],"sources":["../src/finite-number.ts","../src/runtime/supervise/continuation.ts"],"sourcesContent":["export function isFiniteNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value)\n}\n","/**\n * One check ({@link CheckVerdict}; {@link CheckUnavailableError} pauses), one\n * {@link ContinuationPolicy} (`maxBarren`, an optional deadline, no re-prompt default), and one\n * note ({@link composeContinuationNote} owns the facts, {@link ContinuationProfile} owns the\n * words, a play may only append).\n */\n\nimport { mkdir } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport type { TraceAnalysisStore } from '@tangle-network/agent-eval'\nimport { sha256 } from '../../content-digest'\nimport { ValidationError } from '../../errors'\nimport { isFiniteNumber } from '../../finite-number'\nimport type { CheckVerdict } from './completion-gate'\nimport type { DriverBudgetReadout, DriverProgressMark } from './driver-retry'\nimport { writeAtomicDurableFile } from './durable-file'\n\n/** Read a check function's return value into a verdict. Anything but `true` or a passing verdict\n * is a failure: a check fails closed. */\nexport function checkVerdictOf(outcome: unknown): CheckVerdict {\n if (outcome === true) return { pass: true }\n if (typeof outcome !== 'object' || outcome === null || Array.isArray(outcome)) {\n return { pass: false }\n }\n const raw = outcome as Record<string, unknown>\n const items =\n typeof raw.items === 'object' && raw.items !== null && !Array.isArray(raw.items)\n ? Object.fromEntries(\n Object.entries(raw.items as Record<string, unknown>).filter(\n (entry): entry is [string, number] =>\n typeof entry[1] === 'number' && Number.isFinite(entry[1]),\n ),\n )\n : undefined\n const failures = Array.isArray(raw.failures)\n ? raw.failures.filter((line): line is string => typeof line === 'string' && line.trim() !== '')\n : undefined\n return Object.freeze({\n pass: raw.pass === true,\n ...(items === undefined ? {} : { items: Object.freeze(items) }),\n ...(isFiniteNumber(raw.composite) ? { composite: raw.composite } : {}),\n ...(isFiniteNumber(raw.threshold) ? { threshold: raw.threshold } : {}),\n ...(failures === undefined ? {} : { failures: Object.freeze(failures) }),\n ...(typeof raw.review === 'string' && raw.review.trim() !== ''\n ? { review: raw.review.trim() }\n : {}),\n })\n}\n\n/** Items that fail in `verdict`: every item below 1, or the named items of its FAIL lines. */\nexport function failedItems(verdict: CheckVerdict): ReadonlyArray<string> {\n if (verdict.items !== undefined) {\n return Object.entries(verdict.items)\n .filter(([, value]) => value < 1)\n .map(([name]) => name)\n }\n return (verdict.failures ?? []).map((line) => line.slice('FAIL '.length).split(/[\\s:]/u)[0] ?? '')\n}\n\n/** Items that pass in `verdict`. */\nexport function passedItems(verdict: CheckVerdict): ReadonlyArray<string> {\n return Object.entries(verdict.items ?? {})\n .filter(([, value]) => value >= 1)\n .map(([name]) => name)\n}\n\n/** One time the check ran inside the run, whatever started it. */\nexport interface CheckRead {\n /** 1-based count of check reads in this manager, the unavailable ones included. */\n readonly read: number\n /** The driver attempt the read belongs to. */\n readonly attempt: number\n /** Epoch ms. */\n readonly at: number\n /** `submit`: a `submit_result` call. `turn-end`: the turn ended with no accepted result. */\n readonly source: 'submit' | 'turn-end'\n /** Absent when the check could not run. */\n readonly verdict?: CheckVerdict\n /** Why the check could not run. */\n readonly unavailable?: string\n}\n\n// ── The resend rule ──────────────────────────────────────────────────────────────────────────────\n\n/**\n * How a manager with a completion check is sent back when its turn ends unmet.\n *\n * Required for an external manager with a check: Runtime supplies no default, because a retry\n * default in source is a research decision the record must make. There is no re-prompt count.\n * The loop re-enters until the check passes or a bound ends it: cancellation, the budget, or\n * this deadline when one is set. After `maxBarren` turns in a row without progress, each further continuation\n * waits a barren pause first (5 minutes, doubling to 60) and is journaled `barren-pause`; a\n * barren streak never ends the run. A tool `report_blocked` shows\n * really failed is recorded and the loop goes on: a blocked tool is not a terminal condition.\n * Progress means the check's best composite rose, an accepted result, or a worker that delivered.\n */\nexport interface ContinuationPolicy {\n /** No re-entry starts at or after this instant: epoch ms, or an ISO 8601 time. Absent: no clock\n * ends the run; it ends when its check passes, on cancellation, or on a spent budget. */\n readonly deadline?: number | string\n /** Re-entered turns in a row that may end without progress before each further continuation\n * waits a barren pause. Minimum 1. The evidence for 2: repair loses most of its effect within\n * two or three attempts, and a fresh start at the same budget scored higher (Debugging Decay\n * Index). */\n readonly maxBarren: number\n /** Every instruction word of the note. */\n readonly profile: ContinuationProfile\n /** `verbatim` sends the check's FAIL lines, the protected items, and what changed. A check with\n * `feedback: 'pass-only'` overrides this to `off`. */\n readonly failures: 'verbatim' | 'off'\n /** `on` runs the question panel at each continuation and puts its admitted findings in the note.\n * Requires `runPanel`. */\n readonly panel: 'on' | 'off'\n /** `on` states the bar: every check item with its state, the best version's verdict and the\n * gap, the reference result, and the check's review. */\n readonly bar: 'on' | 'off'\n /** The play's registered reference result, for the bar. */\n readonly reference?: string\n /** The best version's verdict on the same check, for the bar. The version loop sets it. */\n readonly best?: { readonly label: string; readonly verdict: CheckVerdict }\n /** The panel's dollar caps. Required with `panel: 'on'`. */\n readonly panelUsd?: { readonly perContinuation: number; readonly perRun: number }\n /** The question panel. Required with `panel: 'on'`. */\n readonly runPanel?: ContinuationPanel\n /** A play's own section, appended after Runtime's sections. It cannot remove or rewrite one. */\n readonly append?: ContinuationAppend\n /**\n * What a re-entered manager's harness session is. `native` (the default) sends the next turn\n * into the same harness session wherever the backend proves it, with the unmet items and what\n * changed. `fresh` starts a new harness session on every re-entry (a continuation, a wake, a\n * failure retry, a pause) whose only input is the full re-entry task: the original task, the\n * check's description and the coordinator's run state. The environment and its files are kept\n * while the provider holds them; only the conversation is new, so whatever the next turn needs\n * must be in the journal, the workspace or Knowledge, never in an earlier turn.\n *\n * Runtime's own drive harnesses (bridge and provider) honor it; a caller's `driveHarness`\n * receives it as `session` and must start a new session on each drive that carries `reentry`.\n */\n readonly session?: 'native' | 'fresh'\n}\n\n/** Resolve and check a policy before any compute. Returns the deadline in epoch ms, or undefined\n * when the policy sets none. */\nexport function admitContinuationPolicy(\n policy: ContinuationPolicy,\n context: string,\n): number | undefined {\n if (typeof policy !== 'object' || policy === null) {\n throw new ValidationError(`${context}: continuation must be an object`)\n }\n const deadlineMs =\n typeof policy.deadline === 'string' ? Date.parse(policy.deadline) : policy.deadline\n if (\n deadlineMs !== undefined &&\n (typeof deadlineMs !== 'number' || !Number.isFinite(deadlineMs) || deadlineMs <= 0)\n ) {\n throw new ValidationError(\n `${context}: continuation.deadline, when set, must be a finite time (epoch ms or ISO 8601)`,\n )\n }\n if (!Number.isInteger(policy.maxBarren) || policy.maxBarren < 1) {\n throw new ValidationError(`${context}: continuation.maxBarren must be an integer >= 1`)\n }\n if (policy.failures !== 'verbatim' && policy.failures !== 'off') {\n throw new ValidationError(`${context}: continuation.failures must be 'verbatim' or 'off'`)\n }\n if (policy.panel !== 'on' && policy.panel !== 'off') {\n throw new ValidationError(`${context}: continuation.panel must be 'on' or 'off'`)\n }\n if (policy.bar !== 'on' && policy.bar !== 'off') {\n throw new ValidationError(`${context}: continuation.bar must be 'on' or 'off'`)\n }\n if (policy.panel === 'on') {\n if (typeof policy.runPanel !== 'function') {\n throw new ValidationError(`${context}: continuation.panel 'on' needs runPanel`)\n }\n const usd = policy.panelUsd\n if (\n usd === undefined ||\n !isFiniteNumber(usd.perContinuation) ||\n !isFiniteNumber(usd.perRun) ||\n usd.perContinuation <= 0 ||\n usd.perRun < usd.perContinuation\n ) {\n throw new ValidationError(\n `${context}: continuation.panel 'on' needs panelUsd with 0 < perContinuation <= perRun`,\n )\n }\n }\n if (policy.append !== undefined && typeof policy.append !== 'function') {\n throw new ValidationError(`${context}: continuation.append must be a function`)\n }\n if (policy.session !== undefined && policy.session !== 'native' && policy.session !== 'fresh') {\n throw new ValidationError(`${context}: continuation.session must be 'native' or 'fresh'`)\n }\n if (policy.reference !== undefined && typeof policy.reference !== 'string')\n throw new ValidationError(`${context}: continuation.reference must be a string`)\n admitContinuationProfile(policy.profile, context)\n return deadlineMs\n}\n\n// ── The profile ──────────────────────────────────────────────────────────────────────────────────\n\n/**\n * Every instruction word of the note. Runtime supplies the facts and their order; this data\n * supplies the words, so the note can be improved (by a person, reflection, or GEPA) without a code\n * change. Templates may name the facts in `CONTINUATION_FACTS` as `{name}`.\n */\nexport interface ContinuationProfile {\n /** Recorded with every note, so each continuation names the words it carried. */\n readonly id: string\n /** Section 1, the verdict. The first line should state the failure as a fact. */\n readonly opening: string\n /** Section 7: what to do before the next submit. */\n readonly plan: string\n /** Section 8: what the harness enforces, and the honest exit. */\n readonly rules: string\n /** Section headings; an empty heading prints the section without one. */\n readonly headings: {\n readonly failures: string\n readonly protected: string\n readonly changed: string\n readonly findings: string\n readonly bar: string\n readonly plan: string\n readonly rules: string\n }\n /** The bar's standing instruction, printed under its heading. */\n readonly barRule?: string\n /** The panel's question templates. `{item}` expands over failed items and `{worker}` over\n * settled workers; a template with neither is asked once. */\n readonly questions?: ReadonlyArray<string>\n /** The panel's model, when the profile chooses one. */\n readonly panelModel?: string\n /** What a new version's director reads about the best version's review, for the version\n * chain's `'review-of-best'`. It may name `{version}`, `{path}` and `{score}`. */\n readonly review?: string\n}\n\n/** The facts a profile template may name. */\nexport const CONTINUATION_FACTS = [\n 'composite',\n 'threshold',\n 'failed',\n 'total',\n 'reads',\n 'owed',\n 'settled',\n 'delivered',\n 'continuation',\n] as const\n\ntype ContinuationFact = (typeof CONTINUATION_FACTS)[number]\n\nconst factNames: ReadonlySet<string> = new Set(CONTINUATION_FACTS)\nconst placeholder = /\\{([a-zA-Z]+)\\}/gu\n\nfunction admitContinuationProfile(profile: ContinuationProfile, context: string): void {\n if (typeof profile !== 'object' || profile === null) {\n throw new ValidationError(`${context}: continuation.profile must be an object`)\n }\n if (typeof profile.id !== 'string' || profile.id.trim() === '') {\n throw new ValidationError(`${context}: continuation.profile.id must be non-empty`)\n }\n const texts: Array<[string, unknown]> = [\n ['opening', profile.opening],\n ['plan', profile.plan],\n ['rules', profile.rules],\n ...Object.entries(profile.headings ?? {}).map(([key, value]): [string, unknown] => [\n `headings.${key}`,\n value,\n ]),\n ...(profile.barRule === undefined ? [] : [['barRule', profile.barRule] as [string, unknown]]),\n ]\n for (const key of ['failures', 'protected', 'changed', 'findings', 'bar', 'plan', 'rules']) {\n if (typeof (profile.headings as Record<string, unknown> | undefined)?.[key] !== 'string') {\n throw new ValidationError(`${context}: continuation.profile.headings.${key} must be a string`)\n }\n }\n for (const [key, text] of texts) {\n if (typeof text !== 'string') {\n throw new ValidationError(`${context}: continuation.profile.${key} must be a string`)\n }\n for (const match of text.matchAll(placeholder)) {\n if (!factNames.has(match[1] ?? '')) {\n throw new ValidationError(\n `${context}: continuation.profile.${key} names {${match[1]}}, which is not a fact Runtime supplies (${CONTINUATION_FACTS.join(', ')})`,\n )\n }\n }\n }\n if (profile.review !== undefined) {\n if (typeof profile.review !== 'string' || profile.review.trim() === '') {\n throw new ValidationError(`${context}: continuation.profile.review must be non-empty`)\n }\n for (const match of profile.review.matchAll(placeholder)) {\n if (!['version', 'path', 'score'].includes(match[1] ?? '')) {\n throw new ValidationError(\n `${context}: continuation.profile.review names {${match[1]}}; it may name {version}, {path} and {score}`,\n )\n }\n }\n }\n if (profile.opening.trim() === '') {\n throw new ValidationError(`${context}: continuation.profile.opening must be non-empty`)\n }\n if (profile.panelModel !== undefined && typeof profile.panelModel !== 'string')\n throw new ValidationError(`${context}: continuation.profile.panelModel must be a string`)\n if (profile.questions !== undefined && !Array.isArray(profile.questions))\n throw new ValidationError(`${context}: continuation.profile.questions must be an array`)\n for (const [index, question] of (profile.questions ?? []).entries()) {\n if (typeof question !== 'string' || question.trim() === '') {\n throw new ValidationError(\n `${context}: continuation.profile.questions[${index}] must be a non-empty string`,\n )\n }\n }\n}\n\n// ── The panel ────────────────────────────────────────────────────────────────────────────────────\n\n/** What the question panel reads for one continuation. */\nexport interface ContinuationPanelInput {\n /** 1-based continuation number. */\n readonly continuation: number\n readonly task: unknown\n /** The check's verdict this note reports; absent when no result reached the check. */\n readonly verdict?: CheckVerdict\n /** Every check read so far, oldest first. */\n readonly reads: ReadonlyArray<CheckRead>\n /** The expanded questions, one per atomic question. */\n readonly questions: ReadonlyArray<string>\n /**\n * The run's own traces, one per agent and named by its node id: the manager's root stream, when\n * it is the root, and each settled worker's tool trace (`src/runtime/supervise/run-traces.ts`). The panel runs only\n * when the run has recorded a span.\n */\n readonly traces: TraceAnalysisStore\n /** Settled workers; each one's trace in `traces` is named by its `id`. */\n readonly workers: ReadonlyArray<{ readonly id: string; readonly label: string }>\n readonly bar?: ContinuationPolicy['best']\n readonly reference?: string\n /** The dollars this panel call may spend. */\n readonly usdCap: number\n readonly signal: AbortSignal\n}\n\n/** One answer the panel proposes for the note. */\nexport interface PanelFinding {\n readonly question: string\n /** The finding, stated as a claim about the run. */\n readonly claim: string\n /** Every `trace://` citation in the answer, and whether the trace store holds it. */\n readonly citations: ReadonlyArray<{ readonly uri: string; readonly resolved: boolean }>\n /** Whether an independent verifier, shown only the cited spans, agreed with the claim. */\n readonly verified: boolean\n /** The failed check items the finding explains, when it names any. */\n readonly items?: ReadonlyArray<string>\n}\n\nexport interface ContinuationPanelResult {\n readonly findings: ReadonlyArray<PanelFinding>\n /** Dollars spent; `null` when the provider reported no cost. Unknown is never zero. */\n readonly usd: number | null\n /** Provider receipts, recorded verbatim in `panel.jsonl`. */\n readonly receipts?: unknown\n}\n\n/** Ask the panel's questions over the run's own traces. */\nexport type ContinuationPanel = (input: ContinuationPanelInput) => Promise<ContinuationPanelResult>\n\n/** A play's own section for one note. Return `undefined` to add nothing this time. */\nexport type ContinuationAppend = (context: {\n readonly continuation: number\n readonly verdict?: CheckVerdict\n readonly reads: ReadonlyArray<CheckRead>\n readonly signal: AbortSignal\n}) => Promise<{ readonly heading: string; readonly text: string } | undefined>\n\n/** A finding that reached the note, with the continuation that admitted it. */\nexport interface AdmittedFinding extends PanelFinding {\n readonly admittedAt: number\n /** Set once every item the finding named passes. */\n readonly resolvedAt?: number\n}\n\n/** Findings reach the note only when every citation resolves, at least two distinct spans are\n * cited, and the independent verifier agreed. The best method in Who&When found the failing step\n * 14.2% of the time, so an unverified finding is noise with a citation. */\nexport function admitFinding(finding: PanelFinding): boolean {\n if (!finding.verified) return false\n if (finding.citations.length === 0) return false\n if (!finding.citations.every((citation) => citation.resolved)) return false\n return new Set(finding.citations.map((citation) => citation.uri)).size >= 2\n}\n\n/** About 1,500 tokens of findings. */\nconst FINDINGS_CHAR_CAP = 6_000\n\n/**\n * Rank the admitted findings by how many failed items they explain, drop repeats, and keep them\n * within the note's cap. Earlier findings stay as they were written (ACE: itemized additions keep\n * detail that repeated rewrites lose); a finding whose items all pass now is marked resolved.\n */\nexport function distillFindings(\n prior: ReadonlyArray<AdmittedFinding>,\n proposed: ReadonlyArray<PanelFinding>,\n failing: ReadonlySet<string>,\n continuation: number,\n): ReadonlyArray<AdmittedFinding> {\n const key = (claim: string) => claim.toLowerCase().replace(/\\s+/gu, ' ').trim()\n const known = new Set(prior.map((finding) => key(finding.claim)))\n const carried = prior.map((finding) =>\n finding.resolvedAt === undefined &&\n (finding.items?.length ?? 0) > 0 &&\n (finding.items ?? []).every((item) => !failing.has(item))\n ? { ...finding, resolvedAt: continuation }\n : finding,\n )\n const fresh = proposed\n .filter(admitFinding)\n .filter((finding) => {\n const k = key(finding.claim)\n if (known.has(k)) return false\n known.add(k)\n return true\n })\n .map((finding) => ({\n finding,\n links: (finding.items ?? []).filter((item) => failing.has(item)).length,\n }))\n .sort((a, b) => b.links - a.links)\n const out: AdmittedFinding[] = [...carried]\n let used = carried\n .filter((finding) => finding.resolvedAt === undefined)\n .reduce((sum, finding) => sum + finding.claim.length, 0)\n for (const { finding } of fresh) {\n if (used + finding.claim.length > FINDINGS_CHAR_CAP) break\n used += finding.claim.length\n out.push({ ...finding, admittedAt: continuation })\n }\n return out\n}\n\n/** Expand the profile's question templates over the failed items and the settled workers. */\nexport function expandQuestions(\n templates: ReadonlyArray<string>,\n failing: ReadonlyArray<string>,\n workers: ReadonlyArray<{ readonly id: string; readonly label: string }>,\n): ReadonlyArray<string> {\n const out: string[] = []\n for (const template of templates) {\n const hasItem = template.includes('{item}')\n const hasWorker = template.includes('{worker}')\n if (!hasItem && !hasWorker) {\n out.push(template)\n continue\n }\n const items = hasItem ? failing : ['']\n const each = hasWorker ? workers.map((worker) => `${worker.id} (${worker.label})`) : ['']\n for (const item of items) {\n for (const worker of each) {\n out.push(template.replaceAll('{item}', item).replaceAll('{worker}', worker))\n }\n }\n }\n return out\n}\n\n// ── The note ─────────────────────────────────────────────────────────────────────────────────────\n\n/** The facts one note is written from. */\nexport interface ContinuationNoteInput {\n readonly profile: ContinuationProfile\n /** 1-based. */\n readonly continuation: number\n /** The verdict this turn ended on; absent when no result has reached the check. */\n readonly verdict?: CheckVerdict\n /** The verdict the previous note reported, for what changed. */\n readonly previous?: CheckVerdict\n /** Check reads so far, the unavailable ones included. */\n readonly reads: number\n /** `verbatim` only when the policy and the check both allow the FAIL lines. */\n readonly failures: 'verbatim' | 'off'\n readonly findings?: ReadonlyArray<AdmittedFinding>\n readonly bar?: {\n readonly best?: ContinuationPolicy['best']\n readonly reference?: string\n }\n readonly appended?: ReadonlyArray<{ readonly heading: string; readonly text: string }>\n /** What the run owes, from the check's description. */\n readonly owed?: string\n readonly progress: DriverProgressMark\n /** Whether `read_continuation` is served to this manager. */\n readonly canReadMore: boolean\n /** Whether submit_result is served to this manager. Absent means unavailable. */\n readonly canSubmitResult?: boolean\n /** Whether the check's score comes from cases the director cannot see. */\n readonly sealed?: boolean\n}\n\n/** At most this many FAIL lines in the note; the rest through `read_continuation`. */\nexport const NOTE_FAILURE_LINES = 40\n\n/**\n * Write one continuation note, sections 1 to 8 of docs/38. Section 9, the run's state, is\n * `composeReentryTask`, which wraps this text. Pure: the same input writes the same note.\n */\nexport function composeContinuationNote(input: ContinuationNoteInput): string {\n const { profile, verdict } = input\n const items = verdict?.items ?? {}\n const total = Object.keys(items).length\n const failing = verdict === undefined ? [] : failedItems(verdict)\n const facts: Record<ContinuationFact, string> = {\n composite: verdict?.composite === undefined ? 'unknown' : format(verdict.composite),\n threshold: verdict?.threshold === undefined ? 'unknown' : format(verdict.threshold),\n failed:\n verdict === undefined || (total === 0 && (verdict.failures?.length ?? 0) === 0)\n ? 'unknown'\n : String(failing.length),\n total: total === 0 ? 'unknown' : String(total),\n reads: String(input.reads),\n owed: input.owed?.trim() || 'not described',\n settled: String(input.progress.settledCount),\n delivered: String(input.progress.deliveredCount ?? 0),\n continuation: String(input.continuation),\n }\n const fill = (text: string) =>\n text.replace(placeholder, (_, name: string) => facts[name as ContinuationFact] ?? `{${name}}`)\n // The opening states a failed verdict. When there is no verdict, or the check passes on a state\n // no result was submitted for, the fact replaces it: the profile cannot state a verdict that\n // does not exist.\n const sections: string[] = [\n verdict === undefined\n ? 'No check verdict is available yet.' +\n (input.canSubmitResult === true\n ? ' Submit a result through submit_result to request the check.'\n : '')\n : verdict.pass\n ? 'The check passes on the current state, but no result has been accepted.' +\n (input.canSubmitResult === true ? ' Call submit_result to request acceptance.' : '')\n : fill(profile.opening).trim(),\n ]\n const section = (heading: string, body: ReadonlyArray<string>) => {\n if (body.length === 0) return\n sections.push([...(heading.trim() === '' ? [] : [`## ${fill(heading)}`]), ...body].join('\\n'))\n }\n if (input.failures === 'verbatim' && verdict !== undefined) {\n const lines = verdict.failures ?? []\n const shown = lines.slice(0, NOTE_FAILURE_LINES)\n const more = lines.length - shown.length\n section(profile.headings.failures, [\n ...shown,\n ...(more > 0\n ? [\n input.canReadMore\n ? `${more} more failure lines: call read_continuation with continuation ${input.continuation}.`\n : `${more} more failure lines are not shown.`,\n ]\n : []),\n ])\n const passing = passedItems(verdict)\n section(profile.headings.protected, passing.length === 0 ? [] : [passing.join(', ')])\n if (input.previous !== undefined) {\n const before = new Set(failedItems(input.previous))\n const now = new Set(failing)\n const fixed = [...before].filter((item) => !now.has(item))\n const broke = [...now].filter((item) => !before.has(item))\n section(profile.headings.changed, [\n ...(fixed.length === 0 ? [] : [`Now passing: ${fixed.join(', ')}.`]),\n ...(broke.length === 0 ? [] : [`Newly failing: ${broke.join(', ')}.`]),\n ...(fixed.length === 0 && broke.length === 0\n ? ['No item changed since the last note.']\n : []),\n ...(input.previous.composite !== undefined && verdict.composite !== undefined\n ? [`Composite: ${format(input.previous.composite)} then ${format(verdict.composite)}.`]\n : []),\n ])\n }\n }\n if (input.findings !== undefined) {\n const open = input.findings.filter((finding) => finding.resolvedAt === undefined)\n const resolved = input.findings.filter((finding) => finding.resolvedAt === input.continuation)\n section(profile.headings.findings, [\n ...open.map(\n (finding) =>\n `- [hypothesis] ${finding.claim}` +\n (finding.items?.length ? ` (items: ${finding.items.join(', ')})` : '') +\n ` Evidence: ${finding.citations.map((citation) => citation.uri).join(', ')}`,\n ),\n ...resolved.map((finding) => `- [resolved] ${finding.claim}`),\n ])\n }\n if (input.bar !== undefined && verdict !== undefined) {\n const body: string[] = []\n if (profile.barRule?.trim()) body.push(fill(profile.barRule).trim())\n for (const [item, value] of Object.entries(items)) {\n const best = input.bar.best?.verdict.items?.[item]\n body.push(\n `- ${item}: ${value >= 1 ? 'passes' : `fails (${format(value)})`}` +\n (best === undefined\n ? ''\n : ` / ${input.bar.best?.label}: ${best >= 1 ? 'passes' : `fails (${format(best)})`}`),\n )\n }\n if (input.bar.best?.verdict.composite !== undefined) {\n body.push(\n `Best version ${input.bar.best.label}: composite ${format(input.bar.best.verdict.composite)}.`,\n )\n }\n if (input.bar.reference?.trim()) body.push(`Reference result: ${input.bar.reference.trim()}`)\n if (verdict.review?.trim()) body.push(`The check's review: ${verdict.review.trim()}`)\n section(profile.headings.bar, body)\n }\n section(profile.headings.plan, profile.plan.trim() === '' ? [] : [fill(profile.plan).trim()])\n section(profile.headings.rules, [\n ...(profile.rules.trim() === '' ? [] : [fill(profile.rules).trim()]),\n ...(input.sealed ? ['The score comes from cases you cannot see.'] : []),\n ])\n for (const appended of input.appended ?? []) {\n section(appended.heading, appended.text.trim() === '' ? [] : [appended.text.trim()])\n }\n return sections.join('\\n\\n')\n}\n\n// ── The record ───────────────────────────────────────────────────────────────────────────────────\n\n/** One continuation as the settle record carries it (`DriverContinuationRecord.continuations`). */\nexport interface ContinuationEntry {\n /** 1-based. */\n readonly continuation: number\n /** The driver attempt whose end this note answered. */\n readonly attempt: number\n /** sha256 of the note's text. */\n readonly noteDigest: string\n readonly profile: string\n readonly switches: {\n readonly failures: 'verbatim' | 'off'\n readonly panel: 'on' | 'off'\n readonly bar: 'on' | 'off'\n }\n /** The verdict the note reported: `null` when no result had reached the check. */\n readonly before: VerdictSummary | null\n /** The verdict at the director's next turn end: `null` when the run ended first. */\n readonly after: VerdictSummary | null\n /** The panel's part: questions asked, findings admitted, dollars (`null` = unknown). */\n readonly panel?: {\n readonly asked: number\n readonly proposed: number\n readonly admitted: number\n readonly usd: number | null\n /** Why the panel asked nothing this time, when it could not run. */\n readonly unavailable?: string\n }\n /** Sections a play appended. */\n readonly appended: number\n}\n\nexport interface VerdictSummary {\n readonly pass: boolean\n readonly composite?: number\n readonly failed?: number\n readonly total?: number\n}\n\nfunction summarizeVerdict(verdict: CheckVerdict | undefined): VerdictSummary | null {\n if (verdict === undefined) return null\n const total = Object.keys(verdict.items ?? {}).length\n return {\n pass: verdict.pass,\n ...(verdict.composite === undefined ? {} : { composite: verdict.composite }),\n ...(total === 0 ? {} : { failed: failedItems(verdict).length, total }),\n }\n}\n\nfunction noteDigest(note: string): string {\n return `sha256:${sha256(note)}`\n}\n\n/** A run directory's continuation files: the root's at `<runDir>/continuations/<n>/`, a nested\n * manager's at `<runDir>/continuations/managers/<owner>/<n>/`. */\nexport const CONTINUATIONS_DIR = 'continuations'\n\n/**\n * Write one continuation's files under `<dir>/<n>/`: `note.md`, `verdict.json`, and\n * `panel.jsonl` when the panel ran. The director reads them through `read_continuation`, because\n * its box cannot read the driver's run directory.\n */\nasync function writeContinuationFiles(\n dir: string,\n continuation: number,\n files: {\n readonly note: string\n readonly verdict?: CheckVerdict\n readonly panel?: ReadonlyArray<unknown>\n },\n): Promise<void> {\n const at = join(dir, String(continuation))\n await mkdir(at, { recursive: true })\n writeAtomicDurableFile(join(at, 'note.md'), `${files.note}\\n`)\n writeAtomicDurableFile(\n join(at, 'verdict.json'),\n `${JSON.stringify(files.verdict ?? null, null, 2)}\\n`,\n )\n if (files.panel !== undefined) {\n writeAtomicDurableFile(\n join(at, 'panel.jsonl'),\n files.panel.map((line) => JSON.stringify(line)).join('\\n') + (files.panel.length ? '\\n' : ''),\n )\n }\n}\n\n// ── The progress reading ─────────────────────────────────────────────────────────────────────────\n\n/** The best composite across `reads`, or `undefined` when no read scored. */\nexport function bestComposite(reads: ReadonlyArray<CheckRead>): number | undefined {\n let best: number | undefined\n for (const read of reads) {\n const value = read.verdict?.composite\n if (value !== undefined && (best === undefined || value > best)) best = value\n }\n return best\n}\n\n/** The readout a continuation is composed from. */\nexport interface ContinuationContext {\n /** The attempt that just completed, 1-based. */\n readonly attempt: number\n /** Continuations this run has already sent. */\n readonly continuations: number\n /** The mark read after the completed drive. */\n readonly progress: DriverProgressMark\n readonly budget: DriverBudgetReadout\n /** Re-entered drives in a row, this one included, that ended without progress. */\n readonly barrenReentries: number\n readonly signal: AbortSignal\n}\n\nfunction format(value: number): string {\n return Number.isInteger(value) ? String(value) : value.toFixed(3).replace(/0+$/u, '')\n}\n\n// ── One manager's continuations ──────────────────────────────────────────────────────────────────\n\n/** What a manager's continuation keeper reads from its run. */\ninterface ContinuationKeeperInput {\n readonly policy: ContinuationPolicy\n readonly task: unknown\n /** What the run owes, from the check's description. */\n readonly owed?: string\n /** The check's feedback mode: `pass-only` keeps the FAIL lines out of every note. */\n readonly feedback?: 'verbatim' | 'pass-only'\n readonly sealed?: boolean\n /** Every check read so far, oldest first. */\n readonly reads: () => ReadonlyArray<CheckRead>\n /** Settled workers, for the panel's `{worker}` questions. */\n readonly workers: () => ReadonlyArray<{ readonly id: string; readonly label: string }>\n /** Where each continuation's files go (`<dir>/<n>/`). Omit to keep them in memory only. */\n readonly dir?: string\n /** The run's own traces for the panel, read at each continuation; `undefined` when none yet. */\n readonly traces?: () => Promise<TraceAnalysisStore | undefined>\n /** Whether `read_continuation` is served to this manager. */\n readonly canReadMore: boolean\n /** Whether submit_result is served to this manager. Absent means unavailable. */\n readonly canSubmitResult?: boolean\n}\n\n/** One manager's continuation state: the notes it was sent and the panel's running ledger. */\nexport interface ContinuationKeeper {\n /** Write the next note. The driver loop calls it only when the check is unmet. */\n compose(context: ContinuationContext): Promise<string>\n /** `read_continuation`: the full record of continuation `n`, or the latest. */\n read(continuation: number | undefined): unknown\n /** The settle record's `continuations`, with the last note's `after` read from the final check. */\n entries(): ReadonlyArray<ContinuationEntry>\n}\n\n/** Build the continuation state for one manager with a check. */\nexport function createContinuationKeeper(input: ContinuationKeeperInput): ContinuationKeeper {\n const { policy } = input\n const failures: 'verbatim' | 'off' = input.feedback === 'pass-only' ? 'off' : policy.failures\n const entries: ContinuationEntry[] = []\n const notes: Array<{\n readonly note: string\n readonly verdict?: CheckVerdict\n readonly panel?: ReadonlyArray<unknown>\n /** The check read the note answered, for the `after` reading. */\n readonly read: number\n }> = []\n let findings: ReadonlyArray<AdmittedFinding> = []\n let panelUsd = 0\n let panelUsdKnown = true\n\n const latestVerdict = (): { verdict?: CheckVerdict; read: number } => {\n const reads = input.reads()\n for (let i = reads.length - 1; i >= 0; i -= 1) {\n const read = reads[i]\n if (read?.verdict !== undefined) return { verdict: read.verdict, read: read.read }\n }\n return { read: 0 }\n }\n\n const closePrevious = (): void => {\n const last = entries.at(-1)\n const lastNote = notes.at(-1)\n if (last === undefined || lastNote === undefined) return\n const latest = latestVerdict()\n entries[entries.length - 1] = {\n ...last,\n after: latest.read > lastNote.read ? summarizeVerdict(latest.verdict) : null,\n }\n }\n\n return {\n async compose(context) {\n closePrevious()\n const continuation = entries.length + 1\n const { verdict, read } = latestVerdict()\n const failing = verdict === undefined ? [] : failedItems(verdict)\n let panelRecord: ContinuationEntry['panel'] | undefined\n let panelLines: unknown[] | undefined\n if (policy.panel === 'on' && policy.runPanel !== undefined && policy.panelUsd !== undefined) {\n const workers = input.workers()\n const questions = expandQuestions(policy.profile.questions ?? [], failing, workers)\n const left = policy.panelUsd.perRun - panelUsd\n const usdCap = Math.min(policy.panelUsd.perContinuation, left)\n // An unknown cost closes the panel for the rest of the run: its cap can no longer be\n // proven, and an unmeasured spend is never read as zero.\n const asking = questions.length > 0 && usdCap > 0 && panelUsdKnown\n let traces: TraceAnalysisStore | undefined\n let unavailable: string | undefined\n if (asking) {\n try {\n traces = await input.traces?.()\n if (traces === undefined) unavailable = 'the run has recorded no trace yet'\n } catch (error) {\n // A trace that cannot be read is the evidence's failure, not the director's: the note\n // goes out without findings, and the record says why.\n unavailable = `the run's traces could not be read: ${error instanceof Error ? error.message : String(error)}`\n }\n }\n if (asking && traces !== undefined) {\n const result = await policy.runPanel({\n continuation,\n task: input.task,\n ...(verdict === undefined ? {} : { verdict }),\n reads: input.reads(),\n questions,\n traces,\n workers,\n ...(policy.best === undefined ? {} : { bar: policy.best }),\n ...(policy.reference === undefined ? {} : { reference: policy.reference }),\n usdCap,\n signal: context.signal,\n })\n if (result.usd === null) panelUsdKnown = false\n else panelUsd += result.usd\n findings = distillFindings(findings, result.findings, new Set(failing), continuation)\n panelRecord = {\n asked: questions.length,\n proposed: result.findings.length,\n admitted: findings.filter((finding) => finding.admittedAt === continuation).length,\n usd: result.usd,\n }\n panelLines = [\n ...result.findings.map((finding) => ({\n kind: 'finding',\n admitted: admitFinding(finding),\n ...finding,\n })),\n ...(result.receipts === undefined\n ? []\n : [{ kind: 'receipts', receipts: result.receipts }]),\n ]\n } else {\n panelRecord = {\n asked: 0,\n proposed: 0,\n admitted: 0,\n usd: 0,\n ...(unavailable === undefined ? {} : { unavailable }),\n }\n }\n }\n const appended = policy.append\n ? await policy.append({\n continuation,\n ...(verdict === undefined ? {} : { verdict }),\n reads: input.reads(),\n signal: context.signal,\n })\n : undefined\n const note = composeContinuationNote({\n profile: policy.profile,\n continuation,\n ...(verdict === undefined ? {} : { verdict }),\n ...(notes.at(-1)?.verdict === undefined ? {} : { previous: notes.at(-1)?.verdict }),\n reads: input.reads().length,\n failures,\n ...(policy.panel === 'on' ? { findings } : {}),\n ...(policy.bar === 'on'\n ? {\n bar: {\n ...(policy.best === undefined ? {} : { best: policy.best }),\n ...(policy.reference === undefined ? {} : { reference: policy.reference }),\n },\n }\n : {}),\n ...(appended === undefined ? {} : { appended: [appended] }),\n ...(input.owed === undefined ? {} : { owed: input.owed }),\n progress: context.progress,\n canReadMore: input.canReadMore,\n canSubmitResult: input.canSubmitResult === true,\n ...(input.sealed === true ? { sealed: true } : {}),\n })\n notes.push({\n note,\n ...(verdict === undefined ? {} : { verdict }),\n ...(panelLines === undefined ? {} : { panel: panelLines }),\n read,\n })\n entries.push({\n continuation,\n attempt: context.attempt,\n noteDigest: noteDigest(note),\n profile: policy.profile.id,\n switches: { failures, panel: policy.panel, bar: policy.bar },\n before: summarizeVerdict(verdict),\n after: null,\n ...(panelRecord === undefined ? {} : { panel: panelRecord }),\n appended: appended === undefined ? 0 : 1,\n })\n if (input.dir !== undefined) {\n await writeContinuationFiles(input.dir, continuation, {\n note,\n ...(verdict === undefined ? {} : { verdict }),\n ...(panelLines === undefined ? {} : { panel: panelLines }),\n })\n }\n return note\n },\n read(continuation) {\n const index = continuation === undefined ? notes.length - 1 : continuation - 1\n const entry = notes[index]\n if (entry === undefined) {\n return {\n found: false,\n reason:\n notes.length === 0\n ? 'no continuation has been sent in this run'\n : `continuations run from 1 to ${notes.length}`,\n }\n }\n return {\n found: true,\n continuation: index + 1,\n note: entry.note,\n // Under `pass-only` the check's lines stay hidden here too.\n verdict:\n failures === 'off' && entry.verdict !== undefined\n ? { pass: entry.verdict.pass }\n : (entry.verdict ?? null),\n findings: findings.filter((finding) => finding.admittedAt <= index + 1),\n }\n },\n entries() {\n closePrevious()\n return entries.map((entry) => ({ ...entry }))\n },\n }\n}\n"],"mappings":"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"}
|