@enderfga/claw-orchestrator 5.1.0 → 6.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/README.md +26 -26
- package/dist/bin/cli.js +107 -1
- package/dist/bin/cli.js.map +1 -1
- package/dist/src/acp-server.d.ts +5 -5
- package/dist/src/acp-server.js +3 -3
- package/dist/src/acp-server.js.map +1 -1
- package/dist/src/autoloop/dispatcher.d.ts +22 -0
- package/dist/src/autoloop/dispatcher.js +71 -13
- package/dist/src/autoloop/dispatcher.js.map +1 -1
- package/dist/src/autoloop/messages.d.ts +10 -0
- package/dist/src/autoloop/messages.js.map +1 -1
- package/dist/src/autoloop/runner.js +6 -0
- package/dist/src/autoloop/runner.js.map +1 -1
- package/dist/src/constants.d.ts +0 -6
- package/dist/src/constants.js +0 -6
- package/dist/src/constants.js.map +1 -1
- package/dist/src/council.d.ts +15 -0
- package/dist/src/council.js +48 -35
- package/dist/src/council.js.map +1 -1
- package/dist/src/dashboard/index.html +191 -6
- package/dist/src/embedded-server.js +132 -9
- package/dist/src/embedded-server.js.map +1 -1
- package/dist/src/fanout.d.ts +30 -1
- package/dist/src/fanout.js +32 -3
- package/dist/src/fanout.js.map +1 -1
- package/dist/src/index.js +359 -4
- package/dist/src/index.js.map +1 -1
- package/dist/src/kernel/agent-step.d.ts +59 -0
- package/dist/src/kernel/agent-step.js +100 -0
- package/dist/src/kernel/agent-step.js.map +1 -0
- package/dist/src/kernel/conditions.d.ts +11 -0
- package/dist/src/kernel/conditions.js +24 -0
- package/dist/src/kernel/conditions.js.map +1 -0
- package/dist/src/kernel/engine.d.ts +319 -0
- package/dist/src/kernel/engine.js +1047 -0
- package/dist/src/kernel/engine.js.map +1 -0
- package/dist/src/kernel/exec.d.ts +43 -0
- package/dist/src/kernel/exec.js +112 -0
- package/dist/src/kernel/exec.js.map +1 -0
- package/dist/src/kernel/file-lock.d.ts +50 -0
- package/dist/src/kernel/file-lock.js +135 -0
- package/dist/src/kernel/file-lock.js.map +1 -0
- package/dist/src/kernel/nodes/agent.d.ts +4 -0
- package/dist/src/kernel/nodes/agent.js +35 -0
- package/dist/src/kernel/nodes/agent.js.map +1 -0
- package/dist/src/kernel/nodes/autoloop.d.ts +78 -0
- package/dist/src/kernel/nodes/autoloop.js +75 -0
- package/dist/src/kernel/nodes/autoloop.js.map +1 -0
- package/dist/src/kernel/nodes/council.d.ts +12 -0
- package/dist/src/kernel/nodes/council.js +88 -0
- package/dist/src/kernel/nodes/council.js.map +1 -0
- package/dist/src/kernel/nodes/fanout.d.ts +11 -0
- package/dist/src/kernel/nodes/fanout.js +63 -0
- package/dist/src/kernel/nodes/fanout.js.map +1 -0
- package/dist/src/kernel/nodes/human-gate.d.ts +4 -0
- package/dist/src/kernel/nodes/human-gate.js +7 -0
- package/dist/src/kernel/nodes/human-gate.js.map +1 -0
- package/dist/src/kernel/nodes/index.d.ts +12 -0
- package/dist/src/kernel/nodes/index.js +21 -0
- package/dist/src/kernel/nodes/index.js.map +1 -0
- package/dist/src/kernel/nodes/router.d.ts +4 -0
- package/dist/src/kernel/nodes/router.js +12 -0
- package/dist/src/kernel/nodes/router.js.map +1 -0
- package/dist/src/kernel/nodes/subflow.d.ts +13 -0
- package/dist/src/kernel/nodes/subflow.js +38 -0
- package/dist/src/kernel/nodes/subflow.js.map +1 -0
- package/dist/src/kernel/nodes/ultraapp.d.ts +60 -0
- package/dist/src/kernel/nodes/ultraapp.js +62 -0
- package/dist/src/kernel/nodes/ultraapp.js.map +1 -0
- package/dist/src/kernel/nodes/verifier.d.ts +14 -0
- package/dist/src/kernel/nodes/verifier.js +84 -0
- package/dist/src/kernel/nodes/verifier.js.map +1 -0
- package/dist/src/kernel/projections.d.ts +42 -0
- package/dist/src/kernel/projections.js +133 -0
- package/dist/src/kernel/projections.js.map +1 -0
- package/dist/src/kernel/repo.d.ts +13 -0
- package/dist/src/kernel/repo.js +64 -0
- package/dist/src/kernel/repo.js.map +1 -0
- package/dist/src/kernel/secrets.d.ts +25 -0
- package/dist/src/kernel/secrets.js +48 -0
- package/dist/src/kernel/secrets.js.map +1 -0
- package/dist/src/kernel/store.d.ts +225 -0
- package/dist/src/kernel/store.js +838 -0
- package/dist/src/kernel/store.js.map +1 -0
- package/dist/src/kernel/templates/index.d.ts +140 -0
- package/dist/src/kernel/templates/index.js +266 -0
- package/dist/src/kernel/templates/index.js.map +1 -0
- package/dist/src/kernel/types.d.ts +326 -0
- package/dist/src/kernel/types.js +19 -0
- package/dist/src/kernel/types.js.map +1 -0
- package/dist/src/run-ledger.d.ts +57 -3
- package/dist/src/run-ledger.js +45 -2
- package/dist/src/run-ledger.js.map +1 -1
- package/dist/src/session-manager.d.ts +176 -129
- package/dist/src/session-manager.js +652 -603
- package/dist/src/session-manager.js.map +1 -1
- package/dist/src/types.d.ts +33 -3
- package/dist/src/ultraapp/build.d.ts +117 -3
- package/dist/src/ultraapp/build.js +319 -3
- package/dist/src/ultraapp/build.js.map +1 -1
- package/dist/src/ultraapp/contract.d.ts +52 -0
- package/dist/src/ultraapp/contract.js +83 -0
- package/dist/src/ultraapp/contract.js.map +1 -0
- package/dist/src/ultraapp/conventions.js +9 -2
- package/dist/src/ultraapp/conventions.js.map +1 -1
- package/dist/src/ultraapp/fix-on-failure.d.ts +21 -2
- package/dist/src/ultraapp/fix-on-failure.js +46 -62
- package/dist/src/ultraapp/fix-on-failure.js.map +1 -1
- package/dist/src/ultraapp/manager.d.ts +107 -2
- package/dist/src/ultraapp/manager.js +305 -86
- package/dist/src/ultraapp/manager.js.map +1 -1
- package/dist/src/verify/baseline.d.ts +73 -0
- package/dist/src/verify/baseline.js +186 -0
- package/dist/src/verify/baseline.js.map +1 -0
- package/dist/src/verify/contract.d.ts +116 -0
- package/dist/src/verify/contract.js +142 -0
- package/dist/src/verify/contract.js.map +1 -0
- package/dist/src/verify/evidence.d.ts +61 -0
- package/dist/src/verify/evidence.js +133 -0
- package/dist/src/verify/evidence.js.map +1 -0
- package/dist/src/verify/runner.d.ts +63 -0
- package/dist/src/verify/runner.js +317 -0
- package/dist/src/verify/runner.js.map +1 -0
- package/openclaw.plugin.json +8 -0
- package/package.json +2 -2
- package/skills/SKILL.md +120 -79
- package/skills/references/acp.md +17 -17
- package/skills/references/autoloop.md +139 -65
- package/skills/references/claude-cli-tracking.md +4 -4
- package/skills/references/cli.md +101 -59
- package/skills/references/council.md +109 -37
- package/skills/references/dashboard.md +34 -6
- package/skills/references/getting-started.md +13 -13
- package/skills/references/inbox.md +4 -4
- package/skills/references/mcp.md +39 -34
- package/skills/references/multi-engine.md +51 -47
- package/skills/references/observability.md +88 -28
- package/skills/references/openai-compat.md +39 -39
- package/skills/references/sessions.md +43 -25
- package/skills/references/tools.md +402 -309
- package/skills/references/ultra.md +45 -45
- package/skills/references/ultraapp.md +126 -50
- package/skills/references/verification.md +187 -0
- package/skills/references/workflow.md +362 -0
- package/dist/src/ultraapp/fix-on-failure-session.d.ts +0 -23
- package/dist/src/ultraapp/fix-on-failure-session.js +0 -51
- package/dist/src/ultraapp/fix-on-failure-session.js.map +0 -1
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The run kernel.
|
|
3
|
+
*
|
|
4
|
+
* A durable executor for workflow runs. It owns what the existing state machines
|
|
5
|
+
* each owned separately and differently: what is running, what to do when a step
|
|
6
|
+
* fails, when to give up, how to stop, and — the part none of them had — how to
|
|
7
|
+
* come back after the process dies.
|
|
8
|
+
*
|
|
9
|
+
* Every mode goes through it. `council_start`, `fanout_start`, `ultraplan_start`,
|
|
10
|
+
* `ultrareview_start` and `autoloop_start` each create a run here; the engines
|
|
11
|
+
* they wrap (`Council`, `Fanout`, the autoloop dispatcher) still do the work,
|
|
12
|
+
* but they no longer own a lifecycle. What that replaced: five result maps, four
|
|
13
|
+
* 30-minute eviction timers, a 5-second poller, two `Set`s fencing a start
|
|
14
|
+
* against a delete, and two incompatible ways of listing past runs across
|
|
15
|
+
* processes.
|
|
16
|
+
*
|
|
17
|
+
* Durability contract, stated precisely: every state transition is checkpointed
|
|
18
|
+
* (atomic `run.json`) and appended to `events.jsonl` before the next step
|
|
19
|
+
* begins, and `resume` restarts at the last node boundary. That makes node
|
|
20
|
+
* execution **at-least-once**, not exactly-once — there is no idempotency key,
|
|
21
|
+
* no attempt lease, and no side-effect commit marker, so a node that died after
|
|
22
|
+
* writing files but before its checkpoint runs again from the top. Workflows
|
|
23
|
+
* whose nodes are not safe to repeat need to make them safe.
|
|
24
|
+
*
|
|
25
|
+
* Ownership contract, equally precisely: this class never writes to a run
|
|
26
|
+
* directly. It holds a `RunGuard` from the store and every change — checkpoint,
|
|
27
|
+
* event, node artifact, terminal verdict — goes through `RunTxn`, which applies
|
|
28
|
+
* the change to a *copy*, commits it under the guard, and adopts the copy only
|
|
29
|
+
* if the disk accepted it. There is no code path from here to `run.json` that
|
|
30
|
+
* skips that, because the raw writers are no longer exported. An owner that has
|
|
31
|
+
* been superseded therefore cannot change the run in memory either: its record
|
|
32
|
+
* stops advancing at the last write the disk agreed to.
|
|
33
|
+
*
|
|
34
|
+
* Control flow is linear with an explicit `router` node for branches and loops.
|
|
35
|
+
* Parallelism is the `fanout` node rather than a general parallel/join construct:
|
|
36
|
+
* fan-out is the shape every existing mode actually needed, and a join barrier
|
|
37
|
+
* would add failure modes (partial joins, orphaned branches) that nothing here
|
|
38
|
+
* would exercise.
|
|
39
|
+
*
|
|
40
|
+
* What a node timeout can and cannot do: it stops the kernel waiting and marks
|
|
41
|
+
* the node failed, but an in-flight agent turn is owned by the session layer and
|
|
42
|
+
* finishes on its own schedule. The kernel does not pretend otherwise.
|
|
43
|
+
*/
|
|
44
|
+
import { EventEmitter } from 'node:events';
|
|
45
|
+
import { type Logger } from '../logger.js';
|
|
46
|
+
import { type AcceptanceContract } from '../verify/contract.js';
|
|
47
|
+
import type { SessionManagerLike } from './agent-step.js';
|
|
48
|
+
import { runDir, summarize, type ListRunsQuery, type RunSummary } from './store.js';
|
|
49
|
+
import { type ConsensusVote, type KernelEvent, type NodeKind, type NodeSpec, type RunRecord, type WorkflowSpec } from './types.js';
|
|
50
|
+
export declare const DEFAULT_NODE_TIMEOUT_MS: number;
|
|
51
|
+
export declare const DEFAULT_MAX_NODE_VISITS = 50;
|
|
52
|
+
/**
|
|
53
|
+
* How long a run about to claim `verified` waits for abandoned attempts to stop.
|
|
54
|
+
*
|
|
55
|
+
* Short on purpose. The wait exists to catch an attempt that is about to finish,
|
|
56
|
+
* not to hold a run hostage to one that never will — a node stuck forever must
|
|
57
|
+
* not stop the run from ending, only from being called verified.
|
|
58
|
+
*/
|
|
59
|
+
export declare const QUIESCE_GRACE_MS = 2000;
|
|
60
|
+
/** Terminal verifier appended when the workflow declares a run-level contract. */
|
|
61
|
+
export declare const IMPLICIT_VERIFIER_ID = "__verify";
|
|
62
|
+
/** How much node text the checkpoint carries inline. The rest goes to disk. */
|
|
63
|
+
export declare const OUTPUT_PREVIEW_CHARS = 4000;
|
|
64
|
+
export interface NodeResult {
|
|
65
|
+
ok: boolean;
|
|
66
|
+
output?: string;
|
|
67
|
+
error?: string;
|
|
68
|
+
evidenceId?: string;
|
|
69
|
+
/** Verifier nodes only: whether the contract passed. */
|
|
70
|
+
passed?: boolean;
|
|
71
|
+
/** Verifier nodes only: the tree digest at the moment the checks finished. */
|
|
72
|
+
treeFingerprint?: string;
|
|
73
|
+
/** human_gate nodes: park the run until a human answers. */
|
|
74
|
+
awaitHuman?: boolean;
|
|
75
|
+
costUsd?: number;
|
|
76
|
+
artifacts?: string[];
|
|
77
|
+
/** Advisory. Recorded on the run; never consulted for completion. */
|
|
78
|
+
consensusVotes?: ConsensusVote[];
|
|
79
|
+
/** Router nodes: the node id control should move to. */
|
|
80
|
+
goto?: string;
|
|
81
|
+
/** Subflow nodes: the child run this node started. */
|
|
82
|
+
childRunId?: string;
|
|
83
|
+
/** Mode-specific payload to checkpoint on the node record. */
|
|
84
|
+
data?: unknown;
|
|
85
|
+
}
|
|
86
|
+
export interface NodeContext {
|
|
87
|
+
runId: string;
|
|
88
|
+
record: RunRecord;
|
|
89
|
+
cwd: string;
|
|
90
|
+
/**
|
|
91
|
+
* 1-based attempt number for this visit. Nodes that name external resources
|
|
92
|
+
* must include it: a timed-out attempt is abandoned, not killed, so it is
|
|
93
|
+
* still running — and still holds a `finally` that tears down whatever it
|
|
94
|
+
* named. Sharing a name with the retry means the dying attempt stops the live
|
|
95
|
+
* one's session.
|
|
96
|
+
*/
|
|
97
|
+
attempt: number;
|
|
98
|
+
manager?: SessionManagerLike;
|
|
99
|
+
logger: Logger;
|
|
100
|
+
signal: {
|
|
101
|
+
aborted: boolean;
|
|
102
|
+
};
|
|
103
|
+
/** Text injected by `steer()` since this node last ran. Consumed by the node. */
|
|
104
|
+
takeSteer(): string[];
|
|
105
|
+
emit(event: KernelEvent): void;
|
|
106
|
+
/** The workflow-level contract, for a `contract: 'run'` verifier node. */
|
|
107
|
+
runContract?: AcceptanceContract;
|
|
108
|
+
/** In-memory values the spec deliberately does not carry. Never persisted. */
|
|
109
|
+
secrets: Record<string, unknown>;
|
|
110
|
+
/** `StartOptions.tag` for the start that launched this node, when one was given. */
|
|
111
|
+
tag?: string;
|
|
112
|
+
/**
|
|
113
|
+
* Publish the live engine object for this node (a `Council`, a `Fanout`, an
|
|
114
|
+
* autoloop dispatcher) so in-flight control — inject, abort, chat — can reach
|
|
115
|
+
* it. In-memory by necessity: you cannot inject into a turn in a process that
|
|
116
|
+
* is gone, and pretending otherwise would be the kind of claim this release
|
|
117
|
+
* exists to remove. After a restart a run resumes; it does not reconnect.
|
|
118
|
+
*/
|
|
119
|
+
setHandle(handle: unknown): void;
|
|
120
|
+
/** Checkpoint mode payload as the node runs, not only when it finishes. */
|
|
121
|
+
publish(data: unknown): void;
|
|
122
|
+
/**
|
|
123
|
+
* Record a child run started by this node, immediately.
|
|
124
|
+
*
|
|
125
|
+
* It has to land before the child finishes, not with the node's result: the
|
|
126
|
+
* whole point is that cancelling the parent can find the child, and a parent
|
|
127
|
+
* cancelled mid-subflow is exactly when the id is not yet in the record.
|
|
128
|
+
*/
|
|
129
|
+
setChild(childRunId: string): void;
|
|
130
|
+
}
|
|
131
|
+
export type NodeExecutor = (node: NodeSpec, ctx: NodeContext) => Promise<NodeResult>;
|
|
132
|
+
export interface KernelOptions {
|
|
133
|
+
manager?: SessionManagerLike;
|
|
134
|
+
logger?: Logger;
|
|
135
|
+
executors?: Partial<Record<NodeKind, NodeExecutor>>;
|
|
136
|
+
/** Default per-node wall clock. */
|
|
137
|
+
nodeTimeoutMs?: number;
|
|
138
|
+
}
|
|
139
|
+
export interface StartOptions {
|
|
140
|
+
runId?: string;
|
|
141
|
+
cwd?: string;
|
|
142
|
+
/** Overrides `spec.contract`. Callers only — never sourced from agent output. */
|
|
143
|
+
contract?: unknown;
|
|
144
|
+
/**
|
|
145
|
+
* Opaque label for THIS start, handed to nodes as `ctx.tag`.
|
|
146
|
+
*
|
|
147
|
+
* A run id can be reused — a start that failed frees it for a retry — so
|
|
148
|
+
* anything the caller keys on the run id can be clobbered by the next start.
|
|
149
|
+
* The tag identifies one attempt at running it.
|
|
150
|
+
*/
|
|
151
|
+
tag?: string;
|
|
152
|
+
/**
|
|
153
|
+
* Values a node needs but the spec must not carry — custom-engine configs,
|
|
154
|
+
* whose `env` holds credentials.
|
|
155
|
+
*
|
|
156
|
+
* These live only in this process's memory. They are never written to
|
|
157
|
+
* `spec.json` or `run.json`, and a resume in another process has to supply
|
|
158
|
+
* them again rather than reading them back, which is the point.
|
|
159
|
+
*/
|
|
160
|
+
secrets?: Record<string, unknown>;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Append the implicit terminal verifier when a run-level contract exists and the
|
|
164
|
+
* author did not already place one. This is what makes `completed` mean "checked".
|
|
165
|
+
*/
|
|
166
|
+
/**
|
|
167
|
+
* Reject a spec that cannot execute correctly, before anything runs.
|
|
168
|
+
*
|
|
169
|
+
* These are all mistakes that used to surface much later and much worse: a
|
|
170
|
+
* duplicate node id silently overwrote a record so one of the two nodes had no
|
|
171
|
+
* state; a `next` or router target naming a node that does not exist failed the
|
|
172
|
+
* run halfway through with `unknown node`; a negative retry or visit bound was
|
|
173
|
+
* accepted and then behaved arbitrarily.
|
|
174
|
+
*/
|
|
175
|
+
export declare function validateSpec(spec: WorkflowSpec): void;
|
|
176
|
+
export declare function prepareSpec(spec: WorkflowSpec): WorkflowSpec;
|
|
177
|
+
export declare class RunKernel extends EventEmitter {
|
|
178
|
+
private readonly manager?;
|
|
179
|
+
private readonly logger;
|
|
180
|
+
private readonly executors;
|
|
181
|
+
private readonly nodeTimeoutMs;
|
|
182
|
+
private readonly live;
|
|
183
|
+
/**
|
|
184
|
+
* This kernel's identity as a run owner.
|
|
185
|
+
*
|
|
186
|
+
* Per instance, not per process: two `RunKernel`s in one process — two
|
|
187
|
+
* SessionManagers is not exotic — would otherwise share a pid and each treat
|
|
188
|
+
* the other's lease as its own, so both would execute the same run.
|
|
189
|
+
*/
|
|
190
|
+
readonly ownerId: string;
|
|
191
|
+
/**
|
|
192
|
+
* Per-run secrets, in memory only. Keyed by run id so a resume in this
|
|
193
|
+
* process can re-use what the start supplied; a resume elsewhere must be
|
|
194
|
+
* given them again.
|
|
195
|
+
*/
|
|
196
|
+
private readonly _secrets;
|
|
197
|
+
/** Caller label for the most recent start of each run. */
|
|
198
|
+
private readonly _tags;
|
|
199
|
+
constructor(opts?: KernelOptions);
|
|
200
|
+
/** Stop and await any live run holding this id, so a reuse cannot overlap it. */
|
|
201
|
+
private _retire;
|
|
202
|
+
/** Register (or replace) the executor for one node kind. */
|
|
203
|
+
setExecutor(kind: NodeKind, executor: NodeExecutor): void;
|
|
204
|
+
/**
|
|
205
|
+
* Open a transaction over a run this kernel has just claimed.
|
|
206
|
+
*
|
|
207
|
+
* The abort signal is created here rather than in `_launch` because the
|
|
208
|
+
* transaction has to be able to stop the run the moment a write is refused,
|
|
209
|
+
* and that can happen before the handle exists.
|
|
210
|
+
*/
|
|
211
|
+
private _open;
|
|
212
|
+
/**
|
|
213
|
+
* Hand a claim back, retrying while the lock is merely busy.
|
|
214
|
+
*
|
|
215
|
+
* Best-effort with a bound: contention here is measured in microseconds, so a
|
|
216
|
+
* few backed-off attempts cover everything short of a wedged filesystem — and
|
|
217
|
+
* if it is wedged, saying so beats retrying forever.
|
|
218
|
+
*/
|
|
219
|
+
private _scheduleRelease;
|
|
220
|
+
start(rawSpec: WorkflowSpec, opts?: StartOptions): Promise<RunRecord>;
|
|
221
|
+
/**
|
|
222
|
+
* Re-attach to a run whose process died. Nodes already marked succeeded are not
|
|
223
|
+
* re-run; the node that was in flight when the process ended is retried from
|
|
224
|
+
* the start, because a half-finished node left no result to trust.
|
|
225
|
+
*/
|
|
226
|
+
resume(runId: string, opts?: {
|
|
227
|
+
restart?: boolean;
|
|
228
|
+
secrets?: Record<string, unknown>;
|
|
229
|
+
tag?: string;
|
|
230
|
+
}): Promise<RunRecord>;
|
|
231
|
+
cancel(runId: string): boolean;
|
|
232
|
+
/** Queue text for the current (or next) agent node. */
|
|
233
|
+
steer(runId: string, text: string): boolean;
|
|
234
|
+
/** Answer a parked `human_gate`. */
|
|
235
|
+
approve(runId: string, approved: boolean): boolean;
|
|
236
|
+
get(runId: string): RunRecord | undefined;
|
|
237
|
+
/**
|
|
238
|
+
* The live engine object a running node published, if the run is still going
|
|
239
|
+
* in this process. Undefined once the node finishes or the process restarts —
|
|
240
|
+
* which is the honest answer, not a gap.
|
|
241
|
+
*/
|
|
242
|
+
handle<T>(runId: string, nodeId: string): T | undefined;
|
|
243
|
+
list(query?: ListRunsQuery): RunSummary[];
|
|
244
|
+
/**
|
|
245
|
+
* Remove a run.
|
|
246
|
+
*
|
|
247
|
+
* `expectTag` guards against deleting the wrong incarnation: a run id is
|
|
248
|
+
* reused when a failed start frees it, so a dying start's cleanup could
|
|
249
|
+
* otherwise delete the retry that had already taken the id. When the tag does
|
|
250
|
+
* not match, nothing is touched.
|
|
251
|
+
*
|
|
252
|
+
* Deleting takes the incarnation with it, which is what makes the id safe to
|
|
253
|
+
* reuse: any guard still held by an abandoned attempt of the deleted run names
|
|
254
|
+
* an incarnation that no longer exists, so it cannot write to whatever takes
|
|
255
|
+
* the id next.
|
|
256
|
+
*/
|
|
257
|
+
delete(runId: string, opts?: {
|
|
258
|
+
expectTag?: string;
|
|
259
|
+
}): boolean;
|
|
260
|
+
/**
|
|
261
|
+
* Resolves when the run reaches a terminal state. A run that already finished
|
|
262
|
+
* (or belongs to another process) resolves from disk, so the caller does not
|
|
263
|
+
* have to race the completion.
|
|
264
|
+
*/
|
|
265
|
+
wait(runId: string): Promise<RunRecord | undefined>;
|
|
266
|
+
shutdown(): Promise<void>;
|
|
267
|
+
private _launch;
|
|
268
|
+
private _setRunState;
|
|
269
|
+
private _setNodeState;
|
|
270
|
+
private _nodeSpec;
|
|
271
|
+
private _nextInOrder;
|
|
272
|
+
private _firstPending;
|
|
273
|
+
private _executeNode;
|
|
274
|
+
/**
|
|
275
|
+
* Wait for abandoned attempts to stop, so a terminal verdict describes a tree
|
|
276
|
+
* nobody is still writing to.
|
|
277
|
+
*
|
|
278
|
+
* A timed-out node is not killed — JS gives us no way to — so a run used to
|
|
279
|
+
* stamp `completed / verified`, then have the abandoned attempt write to the
|
|
280
|
+
* workspace afterwards. The evidence was accurate at the moment it was taken
|
|
281
|
+
* and wrong seconds later, with nothing recording that.
|
|
282
|
+
*/
|
|
283
|
+
private _awaitQuiescence;
|
|
284
|
+
private _run;
|
|
285
|
+
private _runWithRetry;
|
|
286
|
+
private _park;
|
|
287
|
+
/** Node kinds that can change the workspace. Routers and gates cannot. */
|
|
288
|
+
private static readonly SIDE_EFFECT_KINDS;
|
|
289
|
+
/**
|
|
290
|
+
* Fold a node's result into the run — output, artifacts, cost, votes, verdict
|
|
291
|
+
* — as one committed change.
|
|
292
|
+
*
|
|
293
|
+
* Every one of these used to be assigned straight onto the live record, with
|
|
294
|
+
* only the events fenced. A superseded owner therefore returned a record
|
|
295
|
+
* carrying an output, a cost and a passing verdict that the disk had refused.
|
|
296
|
+
*/
|
|
297
|
+
private _absorb;
|
|
298
|
+
/**
|
|
299
|
+
* Decide the terminal state. `completed` requires that nothing refuted the run;
|
|
300
|
+
* a run with no contract completes as `unverified`, which says we did not check
|
|
301
|
+
* rather than claiming success.
|
|
302
|
+
*/
|
|
303
|
+
private _finish;
|
|
304
|
+
/**
|
|
305
|
+
* Why a passing verdict no longer stands, or undefined if it still does.
|
|
306
|
+
*
|
|
307
|
+
* `prepareSpec` cannot enforce this structurally: a router can send control
|
|
308
|
+
* anywhere, so which node runs last is not a property of the spec. And a
|
|
309
|
+
* "nothing after the verifier" rule would be the wrong rule anyway — what
|
|
310
|
+
* matters is not that a node ran, but that the tree moved. So this measures.
|
|
311
|
+
*
|
|
312
|
+
* The caller drops the outcome to `unverified`, not `refuted`: no check
|
|
313
|
+
* failed. We simply no longer know, and saying so is the whole point of having
|
|
314
|
+
* three outcomes.
|
|
315
|
+
*/
|
|
316
|
+
private _verdictWentStale;
|
|
317
|
+
}
|
|
318
|
+
/** Run directory for a given run — re-exported so callers need not import the store. */
|
|
319
|
+
export { runDir, summarize };
|