@ordewell/core 0.12.0 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/{ModeResolver-CHsaoV7M.d.ts → ModeResolver-B64aUZXJ.d.ts} +1 -1
  2. package/dist/{ModeResolver-b_7bPlBS.d.mts → ModeResolver-CA2fUU9h.d.mts} +1 -1
  3. package/dist/{Task-BTEH-ztX.d.mts → Task-CxGgN6I0.d.mts} +503 -16
  4. package/dist/{Task-BTEH-ztX.d.ts → Task-CxGgN6I0.d.ts} +503 -16
  5. package/dist/{chunk-BKTDYGIP.mjs → chunk-2IFKPYPO.mjs} +441 -17
  6. package/dist/chunk-2IFKPYPO.mjs.map +1 -0
  7. package/dist/{chunk-BFLVOYNR.mjs → chunk-FX33UKAD.mjs} +8 -6
  8. package/dist/chunk-FX33UKAD.mjs.map +1 -0
  9. package/dist/{chunk-F6WS3JLQ.mjs → chunk-PKJTN2PD.mjs} +20 -11
  10. package/dist/chunk-PKJTN2PD.mjs.map +1 -0
  11. package/dist/{chunk-HP2LNKST.mjs → chunk-RZ23BMVR.mjs} +345 -134
  12. package/dist/chunk-RZ23BMVR.mjs.map +1 -0
  13. package/dist/chunk-UDUATSCJ.mjs +48 -0
  14. package/dist/chunk-UDUATSCJ.mjs.map +1 -0
  15. package/dist/{IRunner-BwzyUVIL.d.mts → eventStore-CTCSKS9E.d.ts} +916 -129
  16. package/dist/{IRunner-DjJkYwko.d.ts → eventStore-CcB8yELZ.d.mts} +916 -129
  17. package/dist/index.d.mts +677 -97
  18. package/dist/index.d.ts +677 -97
  19. package/dist/index.js +8233 -2450
  20. package/dist/index.js.map +1 -1
  21. package/dist/index.mjs +6951 -1772
  22. package/dist/index.mjs.map +1 -1
  23. package/dist/parsing.d.mts +2 -2
  24. package/dist/parsing.d.ts +2 -2
  25. package/dist/parsing.js +277 -21
  26. package/dist/parsing.js.map +1 -1
  27. package/dist/parsing.mjs +3 -3
  28. package/dist/plan-utils.d.mts +8 -5
  29. package/dist/plan-utils.d.ts +8 -5
  30. package/dist/plan-utils.js +129 -16
  31. package/dist/plan-utils.js.map +1 -1
  32. package/dist/plan-utils.mjs +17 -3
  33. package/dist/{runSettingsText-x-YML2ay.d.mts → runSettingsText-DFVpe6aU.d.mts} +1142 -934
  34. package/dist/{runSettingsText-CvZ40IPv.d.ts → runSettingsText-lKLDsyli.d.ts} +1142 -934
  35. package/dist/testing.d.mts +83 -4
  36. package/dist/testing.d.ts +83 -4
  37. package/dist/testing.js +142 -1
  38. package/dist/testing.js.map +1 -1
  39. package/dist/testing.mjs +126 -2
  40. package/dist/testing.mjs.map +1 -1
  41. package/docker/task.Dockerfile +22 -0
  42. package/package.json +2 -1
  43. package/skills/diagnose/SKILL.md +2 -2
  44. package/skills/explore/SKILL.md +1 -1
  45. package/dist/chunk-BFLVOYNR.mjs.map +0 -1
  46. package/dist/chunk-BKTDYGIP.mjs.map +0 -1
  47. package/dist/chunk-F6WS3JLQ.mjs.map +0 -1
  48. package/dist/chunk-HP2LNKST.mjs.map +0 -1
@@ -1,119 +1,7 @@
1
1
  import { ChildProcess } from 'child_process';
2
- import { b1 as Task, aK as RunnerId, bh as UsageRecord, a$ as SubagentOutcome, aL as RunnerSessionCost, i as DiscoveredModel, ba as TaskSkillSnapshot, p as HandoffCheck } from './Task-BTEH-ztX.mjs';
2
+ import { aB as PlannerAllowlist, b3 as RunnerId, az as PlanStatus, aj as LegacyPlanState, ay as PlanState, bk as SkillsService, bf as SkillInfo, aS as RepoGroupLayout, T as IWorktreeIsolation, ab as IsolationRun, X as IsolationHandoff, ax as PlanIsolation, ac as IsolationTaskRecord, bt as TaskIsolation, ag as IsolationView, a6 as IsolationRemoval, bp as Task, aH as PrepareIntent, aL as PreviousWork, J as HandoffCommit, a3 as IsolationOutcome, aP as RepairEvidence, bE as TreeSnapshot, bq as TaskDiffRead, br as TaskDiffResult, a2 as IsolationMergeResult, ai as LandedWork, b0 as RevertWatch, a9 as IsolationRevertResult, bG as UsageRecord, bm as SubagentOutcome, b4 as RunnerSessionCost, p as DiscoveredModel, bJ as VerificationCheck, bz as TaskSkillSnapshot, b7 as ScriptBody, I as HandoffCheck } from './Task-CxGgN6I0.js';
3
3
  import { z } from 'zod/v4';
4
4
 
5
- /** A script task's time limit when it sets none. */
6
- declare const DEFAULT_SCRIPT_TIMEOUT_MS: number;
7
- /** What a script task runs, its time limit filled in. */
8
- type ScriptBody =
9
- /** Argument vectors run in order with no shell, stopping at the first that fails. */
10
- {
11
- commands: string[][];
12
- timeoutMs: number;
13
- }
14
- /** One script, run by the research shell's interpreter. */
15
- | {
16
- script: string;
17
- timeoutMs: number;
18
- };
19
- type BodyFields = Pick<Task, 'type' | 'commands' | 'script' | 'timeoutMs'>;
20
- /** The body a script task runs; null for any other task, or one whose body the plan's rules refuse. */
21
- declare function scriptBodyOf(task: BodyFields): ScriptBody | null;
22
- /**
23
- * An argument vector as a reader would type it in a shell: a word is quoted
24
- * only where it needs to be, and one holding a character a reader cannot see
25
- * is written with escapes (`$'…'`), so a command is always one line and reads
26
- * as what runs. For reading only; nothing runs it.
27
- */
28
- declare function commandLine(argv: readonly string[]): string;
29
- /**
30
- * A script task's body as the approval card shows it (ADR-0035), so the
31
- * consent is to what will run: each command on a line of its own, or the
32
- * script as written, then the time limit. A character a reader cannot see in
33
- * a script, but for its line breaks and tabs, is shown as its code.
34
- */
35
- declare function scriptBodyText(body: ScriptBody): string;
36
- /**
37
- * A script task as a row shows it: the body {@link scriptBodyText} gives the
38
- * approval card, so what the user read when consenting is what the plan lists.
39
- * A task whose body the plan's rules refuse says so rather than showing nothing.
40
- */
41
- declare function scriptTaskText(task: BodyFields): string;
42
- /** A time limit in the largest units it is a whole number of: "10 minutes", "90 seconds". */
43
- declare function timeLimitText(ms: number): string;
44
-
45
- /**
46
- * The planner's standing approvals (ADR-0026): what runs without asking
47
- * anyone, under every approval mode.
48
- *
49
- * One entry is one of:
50
- *
51
- * - a **command rule**, `gh issue list` or `gcloud * * list`: the binary,
52
- * then words matched against the command's leading arguments, the ones
53
- * before its first flag. A command whose leading words match the rule's
54
- * runs, whatever arguments follow — but the rule must spell out at least
55
- * the words the command's approval scope holds (ADR-0008, T1), so
56
- * `az group` never covers `az group delete`, and a one-word read takes a
57
- * `*` for its argument (`kubectl get *`). `*` stands for one word, and
58
- * inside a word for any run of characters (`describe-*`). An entry equal
59
- * to a scope also matches that scope, as pre-approved scopes always did.
60
- * - an **MCP tool rule**, `mcp:find-*`: a glob over the tool's own name,
61
- * without the server, case-insensitive.
62
- * - a **scope pattern**, anything starting with `/`, `~`, `http://`,
63
- * `https://`, `web_search:`, `mcp__`, `mcp-server:` or a drive letter: matched against an approval's
64
- * scope as ADR-0008 always matched pre-approved entries, `*` matching any
65
- * run of characters.
66
- *
67
- * A leading `!` excludes instead, and an exclusion wins over every rule. A
68
- * command exclusion's words are looked for anywhere among the arguments, in
69
- * order, flags included and case ignored, so `!kubectl *secret*` and
70
- * `!* --endpoint*` hold wherever the word appears; a lone short flag (`-s`)
71
- * also holds inside a bundle (`-As`, `-shost`). `*` as its binary covers
72
- * every command.
73
- */
74
- /** The words a command rule is matched against: a lexed segment's binary and arguments. */
75
- interface CommandWords {
76
- binary: string;
77
- args: readonly string[];
78
- /** How many leading arguments the command's approval scope holds; a rule must cover at least that many. */
79
- scopeWords?: number;
80
- }
81
- interface RuleWord {
82
- matches: (word: string) => boolean;
83
- wildcard: boolean;
84
- }
85
- interface CommandRule {
86
- text: string;
87
- binary: string;
88
- words: RuleWord[];
89
- }
90
- interface PlannerAllowlist {
91
- commands: CommandRule[];
92
- commandExclusions: CommandRule[];
93
- tools: RegExp[];
94
- toolExclusions: RegExp[];
95
- scopes: RegExp[];
96
- scopeExclusions: RegExp[];
97
- }
98
- declare function parseAllowlist(entries: readonly string[]): PlannerAllowlist;
99
- /** The rule that lets this command run unasked, or undefined when none does or an exclusion holds. */
100
- declare function commandAllowedBy(list: PlannerAllowlist, command: CommandWords): string | undefined;
101
- /** Whether an MCP tool, by its own name without the server, runs unasked. */
102
- declare function toolAllowed(list: PlannerAllowlist, tool: string): boolean;
103
- /** Whether an approval scope — a directory, an origin, a tool's full name — is pre-approved. */
104
- declare function scopeAllowed(list: PlannerAllowlist, scope: string): boolean;
105
- /**
106
- * Read-only command families that are safe to run unasked: they read, never
107
- * write a file or change a resource, and need no argument that runs code.
108
- * Absent on purpose: commands that run the repository's own code (test
109
- * runners, builds, package scripts, a package manager the repository pins or
110
- * extends — on an untrusted repository someone else wrote that code), commands
111
- * a repository's own config can point at another endpoint with the user's
112
- * credentials (`.npmrc`, `.sentryclirc`, a Terraform or Pulumi backend), and
113
- * commands whose usual output is a secret.
114
- */
115
- declare const DEFAULT_PLANNER_ALLOWLIST: readonly string[];
116
-
117
5
  /**
118
6
  * Which interpreter runs the planner's `bash` tool, and in which language.
119
7
  *
@@ -736,6 +624,17 @@ interface IConfig {
736
624
  }
737
625
  declare function enabledRunners(cfg: IConfig): RunnerId[];
738
626
 
627
+ type NotificationAction = {
628
+ label: string;
629
+ value: string;
630
+ };
631
+ interface INotification {
632
+ info(msg: string): void;
633
+ warn(msg: string): void;
634
+ error(msg: string): void;
635
+ confirm(msg: string, options: string[]): Promise<string | undefined>;
636
+ }
637
+
739
638
  interface ToolOutcome {
740
639
  success: boolean;
741
640
  output: string;
@@ -882,11 +781,14 @@ interface IFileSystem {
882
781
  endSession?(): void;
883
782
  /** Whether a command can run sealed on this host (ADR-0036 S6); where it cannot, the session's one notice says so. */
884
783
  canSeal?(): Promise<boolean>;
784
+ /** The same adapter at another workspace: what a child's planner reads, its code root being a task's worktree (ADR-0055 D5). */
785
+ rootedAt?(workspace: string): IFileSystem;
885
786
  /** A read-only task's shell at `site`, held to this session's allowlist and never asking (ADR-0046). */
886
787
  taskShell?(site: TaskShellSite): TaskShell;
887
788
  }
888
789
 
889
- declare const taskCompleteInput: z.ZodObject<{
790
+ /** A subplanner's report (ADR-0057 R2): it passes a finding up only by reference, so nothing is reworded on the way, and only its token takes these. */
791
+ declare const subplannerCompleteInput: z.ZodObject<{
890
792
  status: z.ZodEnum<{
891
793
  failed: "failed";
892
794
  done: "done";
@@ -941,6 +843,8 @@ declare const taskCompleteInput: z.ZodObject<{
941
843
  url: z.ZodString;
942
844
  }, z.core.$strip>]>>>;
943
845
  report: z.ZodOptional<z.ZodString>;
846
+ promote: z.ZodOptional<z.ZodArray<z.ZodString>>;
847
+ open: z.ZodOptional<z.ZodArray<z.ZodString>>;
944
848
  }, z.core.$strip>;
945
849
  declare const checkpointInput: z.ZodObject<{
946
850
  question: z.ZodString;
@@ -970,6 +874,24 @@ declare const readTaskInput: z.ZodObject<{
970
874
  attempt: z.ZodOptional<z.ZodNumber>;
971
875
  include_report: z.ZodOptional<z.ZodBoolean>;
972
876
  }, z.core.$strip>;
877
+ declare const plannerPostInput: z.ZodObject<{
878
+ type: z.ZodEnum<{
879
+ attempt: "attempt";
880
+ finding: "finding";
881
+ pin: "pin";
882
+ decision: "decision";
883
+ claim: "claim";
884
+ artifact: "artifact";
885
+ contract: "contract";
886
+ assume: "assume";
887
+ scope_change: "scope_change";
888
+ }>;
889
+ title: z.ZodString;
890
+ key: z.ZodOptional<z.ZodString>;
891
+ value: z.ZodOptional<z.ZodString>;
892
+ detail: z.ZodOptional<z.ZodString>;
893
+ files: z.ZodOptional<z.ZodArray<z.ZodString>>;
894
+ }, z.core.$strip>;
973
895
  declare const savePatchInput: z.ZodObject<{}, z.core.$strip>;
974
896
  declare const applyPatchInput: z.ZodObject<{
975
897
  task: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
@@ -1145,17 +1067,10 @@ declare const answerApprovalInput: z.ZodObject<{
1145
1067
  answer: z.ZodString;
1146
1068
  note: z.ZodOptional<z.ZodString>;
1147
1069
  }, z.core.$strip>;
1148
- declare const answerCheckpointInput: z.ZodObject<{
1149
- task: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
1150
- answer: z.ZodEnum<{
1151
- approve: "approve";
1152
- reject: "reject";
1153
- }>;
1154
- reason: z.ZodOptional<z.ZodString>;
1155
- }, z.core.$strip>;
1156
- type TaskCompleteArgs = z.infer<typeof taskCompleteInput>;
1070
+ type TaskCompleteArgs = z.infer<typeof subplannerCompleteInput>;
1157
1071
  type CheckpointArgs = z.infer<typeof checkpointInput>;
1158
1072
  type ReadTaskArgs = z.infer<typeof readTaskInput>;
1073
+ type PostArgs = z.infer<typeof plannerPostInput>;
1159
1074
  type SavePatchArgs = z.infer<typeof savePatchInput>;
1160
1075
  type ApplyPatchArgs = z.infer<typeof applyPatchInput>;
1161
1076
  type ListRunnersArgs = z.infer<typeof listRunnersInput>;
@@ -1176,7 +1091,7 @@ type RetryTaskArgs = z.infer<typeof retryTaskInput>;
1176
1091
  type MessageTaskArgs = z.infer<typeof messageTaskInput>;
1177
1092
  type SkipTaskArgs = z.infer<typeof skipTaskInput>;
1178
1093
  type AnswerApprovalArgs = z.infer<typeof answerApprovalInput>;
1179
- type AnswerCheckpointArgs = z.infer<typeof answerCheckpointInput>;
1094
+ type AnswerCheckpointArgs = z.infer<typeof delegatingAnswerCheckpointInput>;
1180
1095
  type RunScriptArgs = z.infer<typeof runScriptInput>;
1181
1096
  /** What a handler answers with. `isError` marks a refusal the caller should act on. */
1182
1097
  interface McpToolReply {
@@ -1190,6 +1105,7 @@ interface McpToolReply {
1190
1105
  */
1191
1106
  type CheckpointAnswer = {
1192
1107
  kind: 'continue';
1108
+ note?: string;
1193
1109
  } | {
1194
1110
  kind: 'rejected';
1195
1111
  reason: string;
@@ -1207,6 +1123,8 @@ interface TaskToolHandler {
1207
1123
  checkpoint?: Run<CheckpointArgs>;
1208
1124
  /** A handoff the task may read (ADR-0047), from its attempt's log. */
1209
1125
  readTask?: Run<ReadTaskArgs>;
1126
+ /** An entry on its plan's board (ADR-0057 R8); only a token with a board lists `post`. */
1127
+ post?: Run<PostArgs>;
1210
1128
  /** A read-only task's shell (ADR-0046); only its token lists `run_command`. */
1211
1129
  runCommand?: Run<TaskRunCommandArgs>;
1212
1130
  /** A read-only task's prototype kept as a patch (ADR-0050); only its token lists `save_patch`. */
@@ -1218,6 +1136,10 @@ interface TaskToolHandler {
1218
1136
  webSearch?: Run<WebSearchArgs>;
1219
1137
  }
1220
1138
  interface PlannerToolHandler {
1139
+ /** A handoff below this plan by reference (ADR-0057 R11); only a planner that may hold delegated tasks lists `read`. */
1140
+ readTask?: Run<ReadTaskArgs>;
1141
+ /** An entry on this node's board (ADR-0057 R8); a planner lists it where `read` is. */
1142
+ post?: Run<PostArgs>;
1221
1143
  loadSkill?: Run<LoadSkillArgs>;
1222
1144
  runCommand?: Run<RunCommandArgs>;
1223
1145
  fetch?: Run<FetchArgs>;
@@ -1240,6 +1162,9 @@ interface PlannerToolHandler {
1240
1162
  answerCheckpoint?: Run<AnswerCheckpointArgs>;
1241
1163
  mergeAll?: Run<RunPlanArgs>;
1242
1164
  runScript?: Run<RunScriptArgs>;
1165
+ /** A subplanner's end and its questions, handled by the parent's attempt (ADR-0055 D5); only its token lists them. */
1166
+ taskComplete?: Run<TaskCompleteArgs>;
1167
+ checkpoint?: Run<CheckpointArgs>;
1243
1168
  }
1244
1169
  interface McpTool<H> {
1245
1170
  name: string;
@@ -1251,9 +1176,23 @@ interface McpTool<H> {
1251
1176
  annotations?: {
1252
1177
  readOnlyHint: boolean;
1253
1178
  };
1179
+ /** An older name a call may still use: it is in no list, so it costs nothing and breaks no prompt cache (ADR-0057 R11). */
1180
+ alias?: string;
1254
1181
  /** Validate `args` and hand them to the handler's method for this tool. */
1255
1182
  call(handler: H, args: unknown, context: McpToolContext): Promise<McpToolReply>;
1256
1183
  }
1184
+ /** A tool set as `tools/list` answers with it: what a runner is sent, and pays for. */
1185
+ declare function toolListing<H>(tools: readonly McpTool<H>[]): {
1186
+ annotations?: {
1187
+ readOnlyHint: boolean;
1188
+ } | undefined;
1189
+ name: string;
1190
+ description: string;
1191
+ inputSchema: {
1192
+ [key: string]: unknown;
1193
+ type: "object";
1194
+ };
1195
+ }[];
1257
1196
  /** The task tool whose call settles the attempt (ADR-0022, V1). */
1258
1197
  declare const TASK_COMPLETE_TOOL = "task_complete";
1259
1198
  /**
@@ -1280,6 +1219,11 @@ declare const TASK_TOOLS: readonly McpTool<TaskToolHandler>[];
1280
1219
  * plan's branches.
1281
1220
  */
1282
1221
  declare const READ_ONLY_TASK_TOOLS: readonly McpTool<TaskToolHandler>[];
1222
+ /** What a task's token serves (ADR-0057 R11): the flat list itself where it has no board, so a flat run's does not move by a byte. */
1223
+ declare function taskToolSet({ readOnly, board }: {
1224
+ readOnly?: boolean;
1225
+ board?: boolean;
1226
+ }): readonly McpTool<TaskToolHandler>[];
1283
1227
  /**
1284
1228
  * The planner's execution tools (ADR-0029, #91): each call goes to the
1285
1229
  * session's command seam, which checks it, asks the user where consent needs
@@ -1287,6 +1231,25 @@ declare const READ_ONLY_TASK_TOOLS: readonly McpTool<TaskToolHandler>[];
1287
1231
  */
1288
1232
  declare const PLANNER_EXECUTION_TOOLS: readonly McpTool<PlannerToolHandler>[];
1289
1233
  declare const PLANNER_TOOLS: readonly McpTool<PlannerToolHandler>[];
1234
+ declare const delegatingAnswerCheckpointInput: z.ZodObject<{
1235
+ task: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
1236
+ answer: z.ZodEnum<{
1237
+ approve: "approve";
1238
+ reject: "reject";
1239
+ }>;
1240
+ reason: z.ZodOptional<z.ZodString>;
1241
+ raiseTokens: z.ZodOptional<z.ZodNumber>;
1242
+ }, z.core.$strip>;
1243
+ /**
1244
+ * What a planner's token serves (ADR-0056 M6): the list as a flat planner has
1245
+ * it unless delegation reaches it, so a flat session's tools do not change by
1246
+ * a byte (ADR-0055 D21). A subplanner ends and asks with the tools a runner
1247
+ * does (D4), read-only by the hint since they change no file of the workspace.
1248
+ */
1249
+ declare function plannerToolSet({ delegates, subplanner }?: {
1250
+ delegates?: boolean;
1251
+ subplanner?: boolean;
1252
+ }): readonly McpTool<PlannerToolHandler>[];
1290
1253
 
1291
1254
  /**
1292
1255
  * The Ordewell MCP server (ADR-0022): one loopback listener per process,
@@ -1305,6 +1268,8 @@ interface TaskTokenScope {
1305
1268
  attempt: number;
1306
1269
  /** A read-only task's attempt (ADR-0046): its token lists `run_command`, `fetch` and `web_search` too, and no other task's does. */
1307
1270
  readOnly?: boolean;
1271
+ /** Its plan has a board (ADR-0057 R8): its token lists `post`, and a flat task's does not. */
1272
+ board?: boolean;
1308
1273
  }
1309
1274
  interface PlannerTokenScope {
1310
1275
  sessionId: string;
@@ -1314,6 +1279,10 @@ interface PlannerTokenScope {
1314
1279
  * model would otherwise pick over its own.
1315
1280
  */
1316
1281
  hidden?: readonly string[];
1282
+ /** Its `submit_plan` takes a delegated task (ADR-0055 D1): a flat planner's list does not change. */
1283
+ delegates?: boolean;
1284
+ /** A subplanner's token (ADR-0055 D5): it serves `task_complete` and `checkpoint` too, which its handler sends to the parent's attempt. */
1285
+ subplanner?: boolean;
1317
1286
  }
1318
1287
  /** Where a runner reaches the server and what it presents there. Never put either half in a prompt. */
1319
1288
  interface McpCredential {
@@ -1321,6 +1290,8 @@ interface McpCredential {
1321
1290
  token: string;
1322
1291
  /** The planner tools the token hides ({@link PlannerTokenScope.hidden}), so the runner is told of and pre-allows only what it is served. */
1323
1292
  hidden?: readonly string[];
1293
+ /** Tools it serves past a flat role's, by their names on the server: a subplanner's (ADR-0055 D5), `read` where it may delegate, and `post` where it has a board (ADR-0057 R11). */
1294
+ extraTools?: readonly string[];
1324
1295
  /** The token serves a read-only task's tools ({@link TaskTokenScope.readOnly}), so the runner is told of and pre-allows `run_command`, `fetch` and `web_search`. */
1325
1296
  readOnly?: true;
1326
1297
  }
@@ -1375,6 +1346,8 @@ interface McpClientConfig {
1375
1346
  headers: Record<string, string>;
1376
1347
  /** Planner tools the token hides: a runner must neither pre-allow nor mention them. */
1377
1348
  hidden?: readonly string[];
1349
+ /** Tools served past a planner's: a subplanner's, to pre-allow with the rest (ADR-0055 D5). */
1350
+ extraTools?: readonly string[];
1378
1351
  /** A read-only task's token (ADR-0046): `run_command`, `fetch` and `web_search` are among its tools, for the runner to pre-allow and name. */
1379
1352
  readOnly?: true;
1380
1353
  }
@@ -1787,6 +1760,689 @@ declare class PlannerShellSandbox {
1787
1760
  /** A runner's report on the Ordewell server's connection, in one vocabulary for every runner. */
1788
1761
  type AttachState = 'connected' | 'pending' | 'failed';
1789
1762
 
1763
+ interface SessionMeta {
1764
+ id: string;
1765
+ goal: string;
1766
+ runners: RunnerId[];
1767
+ taskCount: number;
1768
+ status: PlanStatus;
1769
+ createdAt: string;
1770
+ updatedAt: string;
1771
+ }
1772
+ interface SessionData {
1773
+ meta: SessionMeta;
1774
+ /** The full plan state — including conversationHistory, prdMarkdown, and queuedMessages. */
1775
+ plan: LegacyPlanState;
1776
+ }
1777
+
1778
+ interface ILogger {
1779
+ warn(scope: string, message: string, err?: unknown): void;
1780
+ }
1781
+ declare class ConsoleLogger implements ILogger {
1782
+ warn(scope: string, message: string, err?: unknown): void;
1783
+ }
1784
+ declare const defaultLogger: ILogger;
1785
+
1786
+ /**
1787
+ * A path segment for an id that came from outside — a session id from a URL,
1788
+ * a task id a planner wrote. A plain id is used as is; anything that could
1789
+ * climb out of its directory, or is not portable as a file name, is hex-encoded.
1790
+ */
1791
+ declare function idSegment(id: string): string;
1792
+ /**
1793
+ * The directory beside a session's file for what it keeps outside that file —
1794
+ * its task logs (ADR-0018, P1). It goes when the session does. A child's sits
1795
+ * under its root's at every depth, so it goes with its root and no prune or
1796
+ * sweep of a worktree reaches it (ADR-0055 D11).
1797
+ */
1798
+ declare function sessionDataDir(sessionId: string, baseDir?: string, rootSessionId?: string): string;
1799
+ /** Where a child session's state lives. `baseDir` is the state root: the root Session's workspace, never a worktree. */
1800
+ interface ChildSessionPlace {
1801
+ baseDir: string;
1802
+ rootSessionId: string;
1803
+ sessionId: string;
1804
+ }
1805
+ declare function saveSession(plan: LegacyPlanState, goal: string, baseDir?: string, id?: string): SessionMeta;
1806
+ /** Saved beside the child's logs, in the root's directory; `listSessions` never sees it (ADR-0055 D11). */
1807
+ declare function saveChildSession(plan: LegacyPlanState, goal: string, place: ChildSessionPlace): SessionMeta;
1808
+ /** The ids of every child saved under a root, at any depth. */
1809
+ declare function listChildSessions(rootSessionId: string, baseDir?: string): string[];
1810
+ declare function listSessions(baseDir?: string, logger?: ILogger): SessionMeta[];
1811
+ /** A child is read only through its root, and only when asked for (ADR-0055 D17). */
1812
+ declare function loadChildSession(place: ChildSessionPlace, logger?: ILogger): {
1813
+ meta: SessionMeta;
1814
+ plan: LegacyPlanState;
1815
+ } | null;
1816
+ declare function loadSession(sessionId: string, baseDir?: string, logger?: ILogger): {
1817
+ meta: SessionMeta;
1818
+ plan: LegacyPlanState;
1819
+ } | null;
1820
+ declare function loadSessionPlanState(sessionId: string, baseDir?: string, logger?: ILogger): {
1821
+ meta: SessionMeta;
1822
+ plan: PlanState;
1823
+ } | null;
1824
+ declare function getLatestSession(baseDir?: string, logger?: ILogger): {
1825
+ meta: SessionMeta;
1826
+ plan: LegacyPlanState;
1827
+ } | null;
1828
+ declare function deleteSession(sessionId: string, baseDir?: string, logger?: ILogger): boolean;
1829
+
1830
+ /**
1831
+ * Task skills end to end (ADR-0024): a skill reaches a runner only by being
1832
+ * attached to its task in the plan, and Ordewell puts its body in the task's
1833
+ * prompt — so it works the same on every runner, and nothing is written to a
1834
+ * harness's own skills directory.
1835
+ */
1836
+ /** Where a task's skill names are looked up: global first, then the workspace folders it reads. */
1837
+ interface SkillLookup extends Pick<SkillsService, 'findSkill' | 'searchedDirs'> {
1838
+ /**
1839
+ * Set when tasks get worktrees: of `skills`, the workspace ones git will not
1840
+ * carry into them, each SKILL.md path mapped to the folder to commit,
1841
+ * relative to the workspace root.
1842
+ */
1843
+ uncommitted?(skills: readonly SkillInfo[]): Promise<Map<string, string>>;
1844
+ }
1845
+ /**
1846
+ * Where a workspace's skills are read, known without asking git: the repos
1847
+ * of its group in layout order (`['.']` for one repository), and whether
1848
+ * tasks will get worktrees, which only a committed skill reaches.
1849
+ */
1850
+ interface SkillLayout {
1851
+ repos: readonly string[];
1852
+ worktrees: boolean;
1853
+ }
1854
+
1855
+ /**
1856
+ * Where the run's tasks will work: `false` in the shared workspace root;
1857
+ * otherwise each in its own worktree of every repo of the group (ADR-0013,
1858
+ * ADR-0014), which is what decides if tasks on the same file must be ordered.
1859
+ */
1860
+ type IsolatedExecution = false | RepoGroupLayout;
1861
+ interface PlannerModes {
1862
+ autonomousDefault: boolean;
1863
+ /** Not a toggle: a fact about the run. */
1864
+ isolatedExecution: IsolatedExecution;
1865
+ /**
1866
+ * Where the run's tasks will look their skills up (ADR-0024), also a fact
1867
+ * about the run. A plan attaching a planner skill is refused against it,
1868
+ * and a coding agent's submit_plan call is refused in its turn rather than
1869
+ * accepted and then failed. Absent: the plan is not checked.
1870
+ */
1871
+ taskSkills?: SkillLookup;
1872
+ }
1873
+
1874
+ type IsolationNoticeLevel = 'info' | 'warn' | 'error';
1875
+ /**
1876
+ * How an attempt that may run in a worktree gets one: fresh, the kept one for
1877
+ * a repair, restoring the previous attempt's work, or fresh and thrown away
1878
+ * whatever it changes, for a read-only task (ADR-0046).
1879
+ */
1880
+ type AttemptIntent = 'fresh' | 'repair' | 'readOnly' | PrepareIntent;
1881
+ /**
1882
+ * What adopting a persisted run found: nothing to change, landed work git
1883
+ * shows the user has merged since, or a settled run that had nothing left to
1884
+ * hand over and was cleared up.
1885
+ */
1886
+ type AdoptOutcome = 'unchanged' | 'changed' | 'cleared';
1887
+ interface AttemptWorkspace {
1888
+ cwd: string;
1889
+ worktree: boolean;
1890
+ /** The task workspace holding the attempt's worktrees, which `cwd` is in; set with `worktree` when it was prepared. */
1891
+ workspace?: string;
1892
+ /** Set for a `restore` in a worktree; absent in the checkout, where the previous attempt's edits remain. */
1893
+ previousWork?: PreviousWork;
1894
+ }
1895
+ /**
1896
+ * What the controller reports. It never schedules or emits on its own: the
1897
+ * orchestrator turns these into observer events and decides what runs next.
1898
+ */
1899
+ interface IsolationRunListener {
1900
+ /**
1901
+ * The run record changed and should be persisted with the plan. `detached`
1902
+ * is set instead when the record that changed is no longer the plan's own —
1903
+ * a release that outlived the plan load that replaced its run — and belongs
1904
+ * to the session that was left.
1905
+ */
1906
+ changed(detached?: IsolationRun): void;
1907
+ /** A run did not start: `repos` of the group have tracked changes. */
1908
+ blocked(repos: string[]): void;
1909
+ /** An isolated run closed and handed its integration branches over. */
1910
+ handoff(handoff: IsolationHandoff): void;
1911
+ /** The run was cleared up and forgotten: nothing was handed over, or it was discarded. */
1912
+ closed(): void;
1913
+ /** The run is over, discarded or cleared up, whether or not its record stays: nothing it carried goes on (ADR-0045 L5). A Merge all it goes on after is not this. */
1914
+ ended(): void;
1915
+ /** Already said through the notifications; also for a surface that shows no toasts. */
1916
+ notice(level: IsolationNoticeLevel, message: string): void;
1917
+ /** A clean-up took the branches these resolver tasks would merge, and their links with them. */
1918
+ resolversEnded(resolverIds: readonly string[]): void;
1919
+ }
1920
+ interface IsolationRunControllerDeps {
1921
+ isolation: IWorktreeIsolation;
1922
+ config: IConfig;
1923
+ notifications: INotification;
1924
+ workspaceRoot: () => string;
1925
+ /** A child session's state root, which every run it mints keeps (ADR-0055 D11); absent on a flat run. */
1926
+ stateRoot?: string;
1927
+ listener: IsolationRunListener;
1928
+ /**
1929
+ * The tasks no clean-up of the whole run may take a worktree from: an
1930
+ * attempt is running them, or the plan has them in progress or waiting on
1931
+ * the user mid-attempt.
1932
+ */
1933
+ liveTasks: () => ReadonlySet<string>;
1934
+ /** What a task depends on now, directly or not, read as it lands: the plan may let go of that later, and a revert may not (ADR-0054). */
1935
+ landedOn: (taskId: string) => readonly string[];
1936
+ }
1937
+ /**
1938
+ * The lifecycle of a plan's isolation run (ADR-0013, ADR-0014, ADR-0020),
1939
+ * between the scheduler and the git layer: deciding, at a run's first change
1940
+ * task, whether it executes in worktrees, a blocked run and how it goes on,
1941
+ * each attempt's working directory, releasing worktrees, which landed work the
1942
+ * user has merged, the tree check of an ops task, the handoff when the run
1943
+ * closes, and what the user does with it afterwards. The record it keeps
1944
+ * outlives one run — a resumed plan continues it.
1945
+ */
1946
+ declare class IsolationRunController {
1947
+ private readonly isolation;
1948
+ private readonly config;
1949
+ private readonly notifications;
1950
+ private readonly workspaceRoot;
1951
+ private readonly stateRoot;
1952
+ private readonly listener;
1953
+ private readonly liveTasks;
1954
+ private readonly landedOn;
1955
+ private run;
1956
+ /** See {@link mergedRun}. */
1957
+ private merged;
1958
+ /** An adoption stays scoped even while cleanup temporarily leaves no run record. */
1959
+ private adoptions;
1960
+ /** Copied paths already reported for the current run: every task gets the same copies. */
1961
+ private reportedCopies;
1962
+ private gitShortfallSaid;
1963
+ private reportedSetupFailures;
1964
+ /**
1965
+ * How the open run executes; null while no run is open, `undecided` until
1966
+ * its first change task asks. A run is one Execute-Plan or one manual task
1967
+ * run, from its start until it settles or is stopped.
1968
+ */
1969
+ private mode;
1970
+ /** Resolver task id → the conflicted task it resolves; see {@link linkResolver}. */
1971
+ private resolvers;
1972
+ private opening;
1973
+ private opened;
1974
+ /** Bumped by an interrupt, so an activation in flight across it does not open the run it ended. */
1975
+ private activations;
1976
+ /** The start a dirty tree turned away, handed back once the user chooses how to go on. */
1977
+ private blockedStart;
1978
+ /** How many starts it has turned away; a replay can be turned away again in the same run. */
1979
+ private turnedAway;
1980
+ /** The dirty repos behind {@link blockedStart}, for the stash notice. */
1981
+ private blockedRepos;
1982
+ constructor(deps: IsolationRunControllerDeps);
1983
+ /** The plan's run record, open or not; null when the plan has not isolated. */
1984
+ get current(): IsolationRun | null;
1985
+ /** What a child works through: this run's own, so a tree takes one admin lock (ADR-0055 D11). */
1986
+ get childIsolation(): IWorktreeIsolation;
1987
+ /**
1988
+ * The id of the plan's last isolated run once it closed with everything it
1989
+ * landed merged into the user's branch and was cleared up: what tells a
1990
+ * Merge all asked for after it, which has nothing to merge, from one in a
1991
+ * plan that never isolated (ADR-0029). Null while the plan holds a run
1992
+ * record, and once a later run decides how it executes. Saved with the plan.
1993
+ */
1994
+ get mergedRun(): string | null;
1995
+ get isOpen(): boolean;
1996
+ /** How many runs have opened: what tells one run's launches from the next one's. */
1997
+ get epoch(): number;
1998
+ /** The open run has decided whether it isolates. */
1999
+ get decided(): boolean;
2000
+ /** The open run executes in worktrees. */
2001
+ get isolating(): boolean;
2002
+ /** A run is waiting on the user to stash or to go on without isolation. */
2003
+ get blocked(): boolean;
2004
+ /** How many starts a dirty tree has turned away: what tells one wait on it from the next (ADR-0053). */
2005
+ get blockedStarts(): number;
2006
+ /** What the plan persists of isolated execution; null when no run ever isolated. */
2007
+ get planIsolation(): PlanIsolation | null;
2008
+ /** The one guard of every action on the run: a plan that never isolated is a request refused, not a fault. */
2009
+ requireRun(): IsolationRun;
2010
+ /** A task's record in the open run, only while that run isolates. */
2011
+ openRecord(taskId: string): IsolationTaskRecord | undefined;
2012
+ /** Where a task's isolated work stands; null when the plan has no isolation run to speak of. */
2013
+ taskIsolation(taskId: string): TaskIsolation | null;
2014
+ view(): IsolationView | null;
2015
+ /**
2016
+ * Take over a plan's persisted isolation, or none for a plan that has not
2017
+ * isolated yet. Whatever a crashed process left behind for the run — a
2018
+ * worktree still marked active, a directory no record owns — is pruned,
2019
+ * while kept, failed and conflicted worktrees stay for the user. Then git is
2020
+ * asked which landed work the user has merged since the record was saved:
2021
+ * a settled run whose landed work is all in HEAD has nothing left to hand
2022
+ * over, so it is cleared up as Merge all would have, unless it still holds
2023
+ * work that never landed (ADR-0013).
2024
+ *
2025
+ * Deliberately not reported to the listener: adopting is not a change of the
2026
+ * session's own, and a host that adopts without persisting (VS Code's
2027
+ * restore) would otherwise write a new session file on every reload. What
2028
+ * git changed is returned instead, for the caller to save where it can and
2029
+ * announce. A plan loaded meanwhile supersedes this adoption, which then
2030
+ * touches nothing and resolves `unchanged`. `mergedRun` is the plan's saved
2031
+ * {@link mergedRun}.
2032
+ */
2033
+ adopt(state: PlanIsolation | null, mergedRun?: string): Promise<AdoptOutcome>;
2034
+ /** Throws, as {@link hostChild} does, for a task with no worktree: read before a carve, so one that cannot seat a child spends nothing. */
2035
+ requireChildSeat(taskId: string): void;
2036
+ /**
2037
+ * The child session a task's worktree is the code root of, named on the
2038
+ * task's record so a reopen knows that worktree is a child's (ADR-0055 D17),
2039
+ * and the same child again once it is. A task with no worktree has nothing
2040
+ * to host one in: a run that shares the workspace root would root the child
2041
+ * in the user's checkout (D12).
2042
+ */
2043
+ hostChild(taskId: string, mintSessionId: () => string): string;
2044
+ /** The child session seated in a task's worktree, if one is. */
2045
+ childSession(taskId: string): string | undefined;
2046
+ /** A child's run goes, and what that kept or could not let go is said, as a run's own discard says it (ADR-0055 D15). */
2047
+ discardChild(place: ChildSessionPlace): Promise<IsolationRemoval>;
2048
+ /** Open a run if none is, leaving whether it isolates to its first change task. */
2049
+ open(): void;
2050
+ /**
2051
+ * Decide once per run, as its first change task starts, whether it executes
2052
+ * in worktrees (ADR-0020): an ops task needs none, so a run of only ops
2053
+ * tasks never asks. `resume` is what a dirty tree parks until the user
2054
+ * chooses how to go on. Resolves false while the run waits on that choice.
2055
+ */
2056
+ decide(resume: () => Promise<void>): Promise<boolean>;
2057
+ /**
2058
+ * Whether the run in force, or else the next one, gives each task its own
2059
+ * worktrees, and of which repo group — what the planner is told, since it
2060
+ * decides whether tasks on the same file have to be ordered and which shared
2061
+ * paths two tasks must not edit at once. A tree that would block counts as
2062
+ * not isolating: the user may yet run without isolation, and ordering is
2063
+ * the safe rule then.
2064
+ */
2065
+ plannerLayout(): Promise<IsolatedExecution>;
2066
+ /**
2067
+ * Where the workspace's skills are read, and whether tasks get worktrees.
2068
+ * Read synchronously inside a planner turn or a chip edit, so it comes from
2069
+ * the files, not git or the planner's last layout: a restored session is
2070
+ * right from its first edit. The run's repos while it isolates; otherwise
2071
+ * the group the workspace holds, in worktrees unless isolation is off or
2072
+ * this run chose to share the root.
2073
+ */
2074
+ skillLayout(): SkillLayout;
2075
+ /**
2076
+ * Go on with the start a dirty tree turned away. `stash` puts the user's
2077
+ * tracked changes on the git stash first, so the run isolates; `shared` runs
2078
+ * this one run in the workspace root, knowingly; `reread` does nothing to the
2079
+ * tree, so the replay asks about it again (ADR-0053). Returns the parked start
2080
+ * for the caller to replay; null when nothing was parked.
2081
+ */
2082
+ continueBlocked(how: 'stash' | 'shared' | 'reread'): Promise<(() => Promise<void>) | null>;
2083
+ /**
2084
+ * The working directory of an attempt that may run in a worktree — which
2085
+ * attempts do is the attempt kind's to say (see `attemptKind.attemptWorkspace`):
2086
+ * the worktree prepared for it in an isolated run, the kept one for a
2087
+ * conflict repair, else the workspace root. `worktree` says which. Does not
2088
+ * itself report a worktree it creates as a change — the caller does once
2089
+ * the attempt is committed as running, so a spawn abandoned or failed after
2090
+ * this settles is not misreported as a change that stuck.
2091
+ */
2092
+ attemptCwd(task: Task, intent: AttemptIntent): Promise<AttemptWorkspace>;
2093
+ /** The workspace root, for an attempt that runs outside any worktree. */
2094
+ workspaceCwd(task: Task): Promise<{
2095
+ cwd: string;
2096
+ worktree: boolean;
2097
+ }>;
2098
+ private reopenCwd;
2099
+ private prepareCwd;
2100
+ /**
2101
+ * Land a task's work on the run's integration branches. The record is
2102
+ * reported changed once the landing is set and before the first merge, so
2103
+ * a crash mid-landing leaves the tips to roll back to, and again once it
2104
+ * settles. A git error is `failed`, never a throw.
2105
+ */
2106
+ integrate(task: Task, commit?: HandoffCommit): Promise<IsolationOutcome>;
2107
+ private keepLandedOn;
2108
+ /** What a conflict repair's work shows (ADR-0015); git that cannot tell counts against it. */
2109
+ verifyRepair(task: Task): Promise<RepairEvidence>;
2110
+ /** What a repair brings onto the tip it was repaired against (ADR-0055 D14); throws where git cannot say, so nothing lands on a guess. */
2111
+ repairPaths(task: Task): Promise<string[]>;
2112
+ /**
2113
+ * Let go of a task's worktree. `keep` leaves it and its branch for
2114
+ * inspection; otherwise both go. A landing still in flight settles first, so
2115
+ * the worktree is never torn down underneath its merge. Bound to the run
2116
+ * the call was made in: a plan loaded meanwhile adopts its own run, whose
2117
+ * records share these task ids and are not this release's to touch.
2118
+ */
2119
+ release(taskId: string, opts: {
2120
+ keep: boolean;
2121
+ }, landing?: Promise<unknown> | null): Promise<void>;
2122
+ /**
2123
+ * Close the open run. An isolated one hands its integration branch over for
2124
+ * review — unless everything it landed is merged already, at merge gates or
2125
+ * by the run's automatic Merge all, which leaves nothing to hand over, so it
2126
+ * is cleared up as a Merge all would have.
2127
+ */
2128
+ close(): Promise<void>;
2129
+ /**
2130
+ * Whether a task's landed work still waits to be merged into the user's
2131
+ * branch — what holds an ops or user task at its merge gate (ADR-0020). A
2132
+ * task with no record never landed anything to wait for.
2133
+ */
2134
+ awaitsMerge(taskId: string): boolean;
2135
+ /**
2136
+ * Look again for landed work the user has merged — by Merge all, or by hand
2137
+ * with git — or has taken back out. Resolves true when a mark changed.
2138
+ */
2139
+ refreshInHead(): Promise<boolean>;
2140
+ /** Whether any landed work reads as merged: an answer git can take back, if the user takes the merge out. */
2141
+ get readsMerged(): boolean;
2142
+ /** Mark the run's landed work as git finds it now; true when a mark changed. */
2143
+ private findLanded;
2144
+ /** The run landed something and every landing is in the user's HEAD. */
2145
+ private allMerged;
2146
+ /**
2147
+ * The tracked state of the workspace as an attempt whose tree is checked
2148
+ * starts (see `attemptKind.checksTree`), for {@link filesChangedSince}
2149
+ * (ADR-0020). Null where the check does not run: a run that shares the
2150
+ * workspace root, where every task's edits land in it, or a workspace git
2151
+ * cannot isolate at all.
2152
+ */
2153
+ snapshotWorkspace(): Promise<TreeSnapshot | null>;
2154
+ /** Tracked files changed since `snapshot`; none when the run has since gone on in the workspace root. */
2155
+ filesChangedSince(snapshot: TreeSnapshot | null): Promise<string[]>;
2156
+ /**
2157
+ * A stop or a plan load: the open run ends without a handoff and a parked
2158
+ * start is dropped. `keepOpen` spares a run the scheduler is still driving.
2159
+ */
2160
+ interrupt(opts?: {
2161
+ keepOpen?: boolean;
2162
+ }): void;
2163
+ /**
2164
+ * Mark which added task resolves which conflict. The resolver merges the
2165
+ * conflicted task's branch by hand in its own worktree; once that lands, the
2166
+ * conflicted task can land in turn — through the same merge, so a resolver
2167
+ * that did not really bring it along conflicts again instead of being taken
2168
+ * at its word.
2169
+ */
2170
+ linkResolver(resolverId: string, conflictedId: string): void;
2171
+ /** The conflicted task a landed resolver was added for, forgotten as it is returned. */
2172
+ takeResolver(resolverId: string): string | undefined;
2173
+ /** The tasks added to resolve this task's conflict: one, but for a plan saved before that was the rule (ADR-0015). */
2174
+ resolversOf(conflictedId: string): string[];
2175
+ /** The paths a task's branch changed since its base, by their place in the workspace. Throws where they cannot be read: a verdict that rests on them fails closed (ADR-0055 D6). */
2176
+ changedPaths(taskId: string): Promise<string[]>;
2177
+ /** The branch this run's work lands on, which a board's files are compared with (ADR-0057 R9). */
2178
+ get integrationBranch(): string | undefined;
2179
+ /** See {@link IWorktreeIsolation.blobOn}. */
2180
+ blobOn(branch: string, file: string): Promise<string | null | undefined>;
2181
+ taskDiff(taskId: string, options: TaskDiffRead): Promise<TaskDiffResult>;
2182
+ reviewDiff(): Promise<string>;
2183
+ /**
2184
+ * "Merge all": the run's integration branches into whatever the user has
2185
+ * checked out, in every repo or none. During a run it merges what has
2186
+ * landed so far and the run goes on (ADR-0020): its branches stay for the
2187
+ * tasks still to land. Once a settled run merged everything, it has nothing
2188
+ * left to hand over, so it is cleared up and forgotten; a branch the user's
2189
+ * HEAD somehow does not contain stays for the next run's sweep.
2190
+ */
2191
+ merge(): Promise<IsolationMergeResult>;
2192
+ /** What git says of landed work a revert would take; see {@link IWorktreeIsolation.readLanded}. */
2193
+ readLanded(taskIds: readonly string[]): Promise<LandedWork>;
2194
+ /**
2195
+ * Revert tasks' landings on the integration branches (ADR-0054). The record
2196
+ * is reported changed once the tips are set and before the first commit,
2197
+ * again as each commit is made, so a crash leaves it to tell them from
2198
+ * anyone's, and once it settles. Bound to the run it was
2199
+ * asked in: a plan loaded meanwhile has records of its own under these ids,
2200
+ * and is saved without what this would write to that run's branches, so it
2201
+ * stops the revert and leaves them as they were.
2202
+ */
2203
+ revert(taskIds: readonly string[], watch: Omit<RevertWatch, 'persist'>): Promise<IsolationRevertResult>;
2204
+ /**
2205
+ * Worktrees and task branches go; the integration branch and the record stay
2206
+ * for review and merge. Refused while a task of the run is still live.
2207
+ */
2208
+ cleanup(): Promise<void>;
2209
+ /**
2210
+ * The run and everything it made go, and the plan forgets it; the next run
2211
+ * starts afresh. Refused while a task of the run is still live.
2212
+ */
2213
+ discard(): Promise<void>;
2214
+ /** The records of tasks still live, whose worktrees no clean-up of the whole run may take. */
2215
+ private liveRecords;
2216
+ private refuseWhileLive;
2217
+ /**
2218
+ * Clear a settled run up once everything it landed is merged — and only
2219
+ * when nothing else is left in it: a live task, or a worktree holding work
2220
+ * that never landed, keeps the whole run, worktrees and branches, rather
2221
+ * than leaving that work to a deletion.
2222
+ */
2223
+ private clearMerged;
2224
+ /** The records that keep a settled run from being cleared up: live, or holding work that never landed. */
2225
+ private holdouts;
2226
+ /** The run's worktrees and merged branches go; false, said, when git would not let them. */
2227
+ private discardMerged;
2228
+ /** Say what a removal kept back instead of deleting: where the work went, or which worktree stayed. */
2229
+ private report;
2230
+ /** The branches the links' resolvers would merge have gone: the links go, and the scheduler is told of the tasks left. */
2231
+ private endResolvers;
2232
+ /** The run goes from the plan; `merged` names it as {@link mergedRun} when everything it landed was merged. */
2233
+ private forget;
2234
+ private assess;
2235
+ private activate;
2236
+ private begin;
2237
+ /** What earlier runs left merged in the group goes; a failure here is worth a word, never a stopped run. */
2238
+ private sweep;
2239
+ /**
2240
+ * The plan's run carries on while it still has any record: anything landed
2241
+ * means a resumed plan's dependents must start from a tip that holds their
2242
+ * predecessors' work, and anything held — a kept attempt, a conflict, a
2243
+ * repair — is work the user may still want, which a fresh run's mint would
2244
+ * delete. Only a run with no records at all is superseded, and not one that
2245
+ * reverted the tasks it had: a retry starts from its tip (ADR-0054). A record
2246
+ * that names a child holds a code root, on a path that child's own run is tied
2247
+ * to, whether or not a Stop has yet taken it off `active` (ADR-0055 D17).
2248
+ */
2249
+ private continuableRun;
2250
+ /**
2251
+ * A run with no records at all holds only superseded attempts, so it goes —
2252
+ * but its integration branch only where the user's HEAD contains it, as does
2253
+ * that of a run that cannot be continued for another reason (it ran from a
2254
+ * different workspace path): only the user gives landed work up.
2255
+ *
2256
+ * False when `interrupted` came while git was minting: a newer activation
2257
+ * may be minting its own run, so this one is never installed over it, and
2258
+ * is discarded rather than left as branches no record names.
2259
+ */
2260
+ private mint;
2261
+ private reportCopies;
2262
+ private reportSetupFailures;
2263
+ /** Said at the first isolated run, where Ordewell first leans on git and where `git-missing` is said; a child's parent has said it already. */
2264
+ private sayGitShortfall;
2265
+ private tell;
2266
+ }
2267
+
2268
+ /** What a backend can be asked to prove (ADR-0059 L3). */
2269
+ type Guarantee = 'fs.hostHidden' | 'fs.writeScope' | 'net.allowlist' | 'net.noMetadata' | 'cred.unreadable' | 'kernel.separate' | 'limits.memory';
2270
+ /** What a probe found: how, and when. Never declared, so an unproven entry relaxes nothing (L3). */
2271
+ interface GuaranteeProof {
2272
+ proven: boolean;
2273
+ by: string;
2274
+ at: string;
2275
+ }
2276
+ type GuaranteeReport = Record<Guarantee, GuaranteeProof>;
2277
+ /**
2278
+ * Who asks, and in what role, which is policy input: a role is resolved to a
2279
+ * {@link LeaseSpec} before a backend sees one. `child-plan` reserves a node
2280
+ * and no slot (ADR-0055 D18). So does `merge`: it starts no session, and it
2281
+ * reaches a checkout, so a backend hears of it.
2282
+ */
2283
+ interface LeaseRequest {
2284
+ node: {
2285
+ sessionId: string;
2286
+ taskId?: string;
2287
+ };
2288
+ role: 'planner' | 'task' | 'script' | 'child-plan' | 'merge';
2289
+ runner?: RunnerId;
2290
+ }
2291
+ /** Where a lease puts its session. */
2292
+ type LeaseWorkspace = {
2293
+ kind: 'checkout';
2294
+ } | {
2295
+ kind: 'worktree';
2296
+ intent: AttemptIntent;
2297
+ };
2298
+ interface LeaseSpec {
2299
+ /** The attempt's task, as the claim read it; a planner's lease has none. */
2300
+ task?: Task;
2301
+ workspace: LeaseWorkspace;
2302
+ /** Open fails if one of these cannot be proven. */
2303
+ required: readonly Guarantee[];
2304
+ }
2305
+ /** A runner's session, which is what a Continue resumes: the id on the host today, and more behind a container (L2). */
2306
+ interface LeaseSessionState {
2307
+ runner: string;
2308
+ nativeSessionId: string | null;
2309
+ }
2310
+ /**
2311
+ * What outlives a lease (L2): a branch is not the whole result. A synchronous
2312
+ * read: the attempt that ends saves the session before anything can read it.
2313
+ */
2314
+ interface LeaseResult {
2315
+ /** Each repo's branch, by repo path; empty for work with no worktree. */
2316
+ refs: Record<string, string>;
2317
+ sessionState: LeaseSessionState;
2318
+ }
2319
+ /** How a lease's session ended where the host could not watch it (L3); `expired` comes with the first backend that has a time limit. */
2320
+ type LeaseExit = 'oom' | 'killed';
2321
+ /** A runner's launch, as its adapter wrote it for this host. */
2322
+ interface RunnerLaunch {
2323
+ command: string;
2324
+ args: readonly string[];
2325
+ env: Readonly<Record<string, string>>;
2326
+ /** Paths on this host, named in `args`, that the process reads, the one holding its token among them. */
2327
+ files: readonly string[];
2328
+ }
2329
+ /** What this host launches instead. */
2330
+ interface PlacedLaunch {
2331
+ command: string;
2332
+ args: string[];
2333
+ env: Record<string, string>;
2334
+ /** End the process where it runs: killing what this host launched does not reach it. */
2335
+ stop(): void;
2336
+ /** The process has ended. */
2337
+ ended(): void;
2338
+ }
2339
+ /**
2340
+ * Where a lease that does not run its session on this host puts its runner. A
2341
+ * runner is still handed a cwd and nothing more (ADR-0013): only {@link RunnerProcess}
2342
+ * reads this, and an adapter writes the launch it always wrote.
2343
+ */
2344
+ interface RunnerPlacement {
2345
+ place(launch: RunnerLaunch): Promise<PlacedLaunch>;
2346
+ /** Make a listener on this host's loopback reachable from there, and answer the URL to reach it by (`endpoints.mcp`). */
2347
+ reach(url: string): Promise<string>;
2348
+ /** The blob a file holds there, as git would name it, read where the attempt's work is; undefined for what cannot be read. */
2349
+ blob(file: string): Promise<string | undefined>;
2350
+ }
2351
+ /** One repository of an attempt's worktree, for a backend that keeps a copy of it elsewhere. */
2352
+ interface LeaseRepo {
2353
+ /** Relative to the workspace; `.` for a lone repository. */
2354
+ path: string;
2355
+ /** The repository on this host. */
2356
+ root: string;
2357
+ /** Its worktree for this task. */
2358
+ worktree: string;
2359
+ branch: string;
2360
+ integrationBranch: string;
2361
+ /** What Ordewell linked into the worktree, which is no attempt's work. */
2362
+ linked: readonly string[];
2363
+ }
2364
+ interface OpenLease {
2365
+ workspace: {
2366
+ cwd: string;
2367
+ /** The task workspace holding its worktrees, when it has any. */
2368
+ writable?: string;
2369
+ /** Whether it runs in a worktree prepared for it rather than at the root. */
2370
+ worktree: boolean;
2371
+ /** What became of the previous attempt's work, where a restore was asked for. */
2372
+ previousWork?: PreviousWork;
2373
+ /** Each repository of its worktree, plural as a repo group's are (ADR-0014). */
2374
+ repos?: readonly LeaseRepo[];
2375
+ };
2376
+ guarantees: GuaranteeReport;
2377
+ exportResult(session: LeaseSessionState): LeaseResult;
2378
+ /** Set where the runner does not run on this host. */
2379
+ placement?: RunnerPlacement;
2380
+ /** How its session ended, once it has, where the backend can tell (L3). */
2381
+ ended?(): Promise<LeaseExit | null>;
2382
+ }
2383
+ /**
2384
+ * Taken in the claim's synchronous step (L1). What it reserves is given back at
2385
+ * {@link release}; the workspace it opened need not go with it: a worktree
2386
+ * outlives the lease that made it, for a repair or a continue, so what becomes
2387
+ * of it is {@link ExecutionBackend.letGo}.
2388
+ */
2389
+ interface ReservedLease {
2390
+ readonly id: string;
2391
+ /** Whether this lease holds a slot: a delegated task's and a merge's do not. */
2392
+ readonly holdsSlot: boolean;
2393
+ /** Runs after the claim, where the workspace is made. Rejects without making one once `signal` has aborted. */
2394
+ open(spec: LeaseSpec, signal: AbortSignal): Promise<OpenLease>;
2395
+ /** Idempotent and synchronous: an attempt's end frees its slot before anything awaits (ADR-0029). */
2396
+ release(reason: string): void;
2397
+ }
2398
+ /** One task's workspace, as a restart finds it. */
2399
+ interface LeaseRecord {
2400
+ taskId: string;
2401
+ status: string;
2402
+ worktrees: readonly string[];
2403
+ }
2404
+ interface ExecutionBackend {
2405
+ /** What it can prove now. */
2406
+ probe(): Promise<GuaranteeReport>;
2407
+ /** Why this may not be reserved now, or null. Synchronous, and changes nothing: it is also asked with no claim to follow. */
2408
+ refusal(request: LeaseRequest): string | null;
2409
+ /** Synchronous, inside the claim. A refusal keeps the Session that asked, for what frees next. */
2410
+ reserve(request: LeaseRequest): {
2411
+ lease: ReservedLease;
2412
+ } | {
2413
+ refused: string;
2414
+ };
2415
+ /** What becomes of a task's workspace, with no lease needed: a kept worktree outlives the one that opened it. */
2416
+ letGo(taskId: string, how: {
2417
+ keep: boolean;
2418
+ landing?: Promise<unknown> | null;
2419
+ reason: string;
2420
+ }): Promise<void>;
2421
+ /** What a restart finds. Starts nothing (ADR-0044). */
2422
+ list(): Promise<readonly LeaseRecord[]>;
2423
+ /**
2424
+ * Bring a task's work to its worktree, for a backend that keeps it elsewhere:
2425
+ * the half of a result that takes time and can be refused (L2). By task, since
2426
+ * a landing can come after its attempt, as a Mark complete does. Absent, the
2427
+ * work is there already. Rejects with why it must not land.
2428
+ */
2429
+ collect?(taskId: string): Promise<void>;
2430
+ /**
2431
+ * Everything it has running has gone and what was on its way has arrived, as
2432
+ * the Session around it closes. Absent, nothing outlives an attempt's runner.
2433
+ * What a next attempt comes back to stays, and it never rejects.
2434
+ */
2435
+ settle?(): Promise<void>;
2436
+ /** The workspace root's repositories, where a run knows them: a repo group's root is no repository to ask. */
2437
+ checkoutRepos?(): readonly LeaseRepo[];
2438
+ /**
2439
+ * Let go of what its tree left where only it can reach, as a Clean up gives the
2440
+ * run up. Absent, there is nothing but the worktrees. Reports what it could not
2441
+ * clear, and never rejects: it is no reason for a clean-up to fail.
2442
+ */
2443
+ reclaim?(): Promise<void>;
2444
+ }
2445
+
1790
2446
  /**
1791
2447
  * The harness-planner transport contract (ADR-0009).
1792
2448
  *
@@ -2090,6 +2746,10 @@ interface PlannerStartOptions extends AgentStartCommon {
2090
2746
  * these are the only ones it gets, and each is handed over as parsed.
2091
2747
  */
2092
2748
  projectServers?: ProjectMcpServer[];
2749
+ /** The harness's own subagents are off for this session (ADR-0056 M6), each runner by its own switch. Absent means as the harness has them. */
2750
+ noSubagents?: true;
2751
+ /** What a subplanner's process loads of the user's setup (ADR-0057 R11); absent means `user`. */
2752
+ runnerConfig?: TaskRunnerConfig;
2093
2753
  }
2094
2754
  /**
2095
2755
  * What a runner manifest says the task's mode and effort mean (ADR-0001),
@@ -2297,6 +2957,8 @@ interface AgentProcessDeps {
2297
2957
  workspaceEnv?: (cwd: string) => Promise<Record<string, string>>;
2298
2958
  /** Builds the sandbox around a planner's own shell (ADR-0036 N2). Defaults to the host's probe. */
2299
2959
  nativeShellSandbox?: () => PlannerShellSandbox;
2960
+ /** Where a lease put this runner, when not on this host (ADR-0059 L5). */
2961
+ placement?: RunnerPlacement;
2300
2962
  }
2301
2963
  /** Builds the adapter for one runner id, or null when that runner cannot plan. */
2302
2964
  type AgentAdapterFactory = (runner: string, deps: AgentProcessDeps) => AgentAdapter | null;
@@ -2782,7 +3444,7 @@ interface IRunnerSession {
2782
3444
  * The runner's `task_complete` calls on this attempt's token (ADR-0022):
2783
3445
  * the only completion evidence, for `VerdictEngine` to weigh.
2784
3446
  */
2785
- onTaskComplete(listener: (report: TaskCompleteArgs) => void): void;
3447
+ onTaskComplete(listener: (report: TaskCompleteArgs, refuted?: VerificationCheck) => void): void;
2786
3448
  /**
2787
3449
  * Answers the runner's `checkpoint` calls (ADR-0022, V5): the call stays
2788
3450
  * open until the returned promise settles, and its result is the answer.
@@ -2824,6 +3486,8 @@ interface IRunner {
2824
3486
  * manifest's env still wins over them.
2825
3487
  */
2826
3488
  env?: Record<string, string>;
3489
+ /** A delegated task's attempt (ADR-0055 D3): the task, for {@link ChildPlanRunner} to give its child. */
3490
+ delegated?: Task;
2827
3491
  /** The runner's own session to continue in (ADR-0018, K1). */
2828
3492
  resumeSessionId?: string;
2829
3493
  /** What was counted of that session's running cost before, so its first turn is counted from there. */
@@ -2848,6 +3512,8 @@ interface IRunner {
2848
3512
  * attempt. Runners ignore it; it is for what wraps one to record (task logs).
2849
3513
  */
2850
3514
  skills?: readonly TaskSkillSnapshot[];
3515
+ /** Where the attempt's lease put this runner, when not on this host (ADR-0059 L5). */
3516
+ placement?: RunnerPlacement;
2851
3517
  /** Something the user should know about how the spawn went that did not stop it — a respawn, most often. */
2852
3518
  onNotice?: (message: string) => void;
2853
3519
  /**
@@ -2869,6 +3535,8 @@ interface IRunner {
2869
3535
  runnerConfig?: TaskRunnerConfig;
2870
3536
  /** A script task's body (ADR-0035): only the script runner reads it, and it runs nothing else. */
2871
3537
  script?: ScriptBody;
3538
+ /** A read-only script's shell (ADR-0055 D8): its body runs sealed there, in the worktree it was cut. */
3539
+ sealed?: TaskShell;
2872
3540
  /**
2873
3541
  * A read-only attempt's shell (ADR-0046): its token serves `run_command`
2874
3542
  * from it, and only an attempt that has one is given that tool.
@@ -2879,12 +3547,14 @@ interface IRunner {
2879
3547
  * arrives (ADR-0047): a refusal is the call's result, and nothing is
2880
3548
  * recorded. Without one, a `task` reference resolves against no plan.
2881
3549
  */
2882
- checkHandoff?: (completion: TaskCompleteArgs) => HandoffCheck<TaskCompleteArgs>;
3550
+ checkHandoff?: (completion: TaskCompleteArgs) => HandoffCheck<TaskCompleteArgs> | Promise<HandoffCheck<TaskCompleteArgs>>;
2883
3551
  /**
2884
- * Answers the attempt's `read_task` calls (ADR-0047), against the plan
3552
+ * Answers the attempt's `read` calls (ADR-0047), against the plan
2885
3553
  * and the session's task logs. Without one the call says it is not available.
2886
3554
  */
2887
- readTask?: (args: ReadTaskArgs) => McpToolReply;
3555
+ readTask?: (args: ReadTaskArgs) => McpToolReply | Promise<McpToolReply>;
3556
+ /** Answers the attempt's `post` calls (ADR-0057 R8). Given only where its plan has a board, which is what lists the tool. */
3557
+ post?: (args: PostArgs) => McpToolReply | Promise<McpToolReply>;
2888
3558
  /**
2889
3559
  * Answers a read-only attempt's `save_patch` calls (ADR-0050): its shell
2890
3560
  * captures the worktree's changes and the attempt keeps them. Without one
@@ -2912,4 +3582,121 @@ interface IRunner {
2912
3582
  activeCount: number;
2913
3583
  }
2914
3584
 
2915
- export { type McpToolContext as $, AUTO_COMMANDS as A, type BashOptions as B, type CatalogModel as C, DEFAULT_PLANNER_ALLOWLIST as D, type DiscoveryCommand as E, type EditPlanArgs as F, type FetchAllProviderModelsOptions as G, type FindSymbolOptions as H, GIT_READONLY_SUBCOMMANDS as I, GREP_DEFAULT_HEAD_LIMIT as J, type GlobOptions as K, type GrepOptions as L, type GrepOutputMode as M, type IApproval as N, type IConfig as O, type IFileSystem as P, type IRunner as Q, type IRunnerSession as R, type InvokedCommand as S, LineBuffer as T, type ListModelsArgs as U, type ListRunnersArgs as V, type LoadSkillArgs as W, type McpClientConfig as X, type McpCredential as Y, type McpRefusal as Z, type McpTool as _, type AgentAdapter as a, type SealedAvailability as a$, type McpToolReply as a0, type MessageTaskArgs as a1, ModelCatalog as a2, type ModelShortcut as a3, ORCHESTRATOR_SHORTCUTS as a4, ORDEWELL_MCP_PATH as a5, ORDEWELL_MCP_SERVER_NAME as a6, type OneTaskArgs as a7, type OrchestratorOption as a8, OrdewellMcpServer as a9, type RunCommandArgs as aA, type RunPlanArgs as aB, type RunnerAuthSpec as aC, type RunnerAuthStatus as aD, type RunnerCommand as aE, type RunnerCommandKind as aF, type RunnerEntry as aG, type RunnerEnv as aH, type RunnerFeatures as aI, type RunnerManifest as aJ, type RunnerMcpServer as aK, type RunnerMode as aL, type RunnerModelDiscovery as aM, type RunnerModelRef as aN, RunnerRegistry as aO, SEALED_LIMITS as aP, SEARCH_EXCLUSIONS as aQ, type SandboxBackend as aR, type SandboxInvocation as aS, type SandboxLaunch as aT, type SandboxLimits as aU, type SandboxProfile as aV, type ScriptBody as aW, type ScriptExit as aX, type ScriptFullOutput as aY, type ScriptRun as aZ, type ScriptStatus as a_, type OwnSealedRuns as aa, type OwnerOnlyFile as ab, PLANNER_EXECUTION_TOOLS as ac, PLANNER_SANDBOX_DOCS as ad, PLANNER_TOOLS as ae, type PlannerAllowlist as af, type PlannerBackendId as ag, type PlannerSandboxAvailability as ah, type PlannerSandboxDeps as ai, PlannerShellSandbox as aj, type PlannerStartOptions as ak, type PlannerTokenScope as al, type PlannerToolHandler as am, type ProjectMcpServer as an, type ProviderCredentialSource as ao, type ProviderModelLists as ap, type ProviderModelsResult as aq, type QueuedTaskMessage as ar, READ_ONLY_TASK_TOOLS as as, REFUSED_COMMANDS as at, type ReadFileOpts as au, type ReadTaskArgs as av, type ResearchShell as aw, type ResearchShellDeps as ax, type RetryTaskArgs as ay, type RuleWord as az, type AgentAdapterFactory as b, toolAllowed as b$, type SealedRunOptions as b0, type ShellDialect as b1, type ShellLaunch as b2, type SpawnFn as b3, type StandingDecision as b4, type StructuredEvent as b5, type StructuredTurnEnd as b6, type SubmitPlanArgs as b7, TASK_COMPLETE_TOOL as b8, TASK_COMPLETION_CONTRACT as b9, commandLine as bA, effectiveApprovalMode as bB, enabledRunners as bC, fetchAllProviderModels as bD, findRunnerCommand as bE, isGranted as bF, isRunnerApproval as bG, knownModelId as bH, mcpClientConfig as bI, ownerOnlyConfigFile as bJ, parseAllowlist as bK, parseApprovalModeSetting as bL, researchShellWarning as bM, researchToolsPath as bN, resolveModelShortcut as bO, resolvePlannerSandbox as bP, resolveProvider as bQ, resolveResearchShell as bR, scopeAllowed as bS, scriptBodyOf as bT, scriptBodyText as bU, scriptTaskText as bV, sharedMcpServer as bW, taskCompletionContract as bX, timeLimitText as bY, toApprovalDecision as bZ, toOrchestratorOptions as b_, TASK_SEALED_LIMITS as ba, TASK_TOOLS as bb, type TaskCompleteArgs as bc, type TaskDiffArgs as bd, type TaskMessageFrom as be, type TaskModeAgentAdapter as bf, TaskModeUnsupportedError as bg, type TaskOutputArgs as bh, type TaskQueryArgs as bi, type TaskRunCommandArgs as bj, type TaskRunnerConfig as bk, type TaskRunnerFlags as bl, type TaskShell as bm, type TaskShellSite as bn, type TaskStartOptions as bo, type TaskTokenScope as bp, type TaskToolHandler as bq, type TaskWebReads as br, type ToolOutcome as bs, type UsageLimitSignal as bt, approvalScopes as bu, classifyCommand as bv, clearPlannerSandboxCache as bw, clearResearchShellCache as bx, collectProviderCredentials as by, commandAllowedBy as bz, type AgentEvent as c, type AgentProcessDeps as d, type AgentStartOptions as e, type AiProvider as f, type AllProviderModels as g, type AnswerApprovalArgs as h, type ApplyPatchArgs as i, type ApprovalAnswer as j, type ApprovalDecision as k, type ApprovalKind as l, type ApprovalMode as m, type ApprovalModeSetting as n, ApprovalPolicy as o, type ApprovalPolicyOptions as p, type ApprovalRequest as q, type ApprovalSource as r, type AttachState as s, type CheckpointAnswer as t, type CheckpointArgs as u, type CommandClassification as v, type CommandTier as w, type CommandWords as x, DEFAULT_SCRIPT_TIMEOUT_MS as y, DENY_ALL as z };
3585
+ declare const BOARD_TYPES: readonly ["finding", "claim", "attempt", "artifact", "contract", "assume", "scope_change", "decision", "pin"];
3586
+ type BoardEntryType = (typeof BOARD_TYPES)[number];
3587
+ /** `file` evidence, with the blobs R9 compares: Ordewell reads both as the entry is posted, so neither is an author's claim. */
3588
+ interface BoardFile {
3589
+ kind: 'file';
3590
+ path: string;
3591
+ /** The file as its author had it, where it could be read. */
3592
+ sha?: string;
3593
+ /** What the board's branch held then, absent where it held no such file. */
3594
+ tip?: string;
3595
+ }
3596
+ /** What an author sends. */
3597
+ interface BoardPost {
3598
+ type: BoardEntryType;
3599
+ title: string;
3600
+ detail?: string;
3601
+ /** What `contested` compares (R9): entries with one key and different values. */
3602
+ key?: string;
3603
+ value?: string;
3604
+ files?: string[];
3605
+ }
3606
+ /** Whose words an entry is, as the token that posted it says and never the entry. */
3607
+ interface BoardAuthor {
3608
+ node: NodePath;
3609
+ /** Its task's label in that plan; absent for that plan's planner. */
3610
+ task?: string;
3611
+ attempt?: number;
3612
+ }
3613
+ interface BoardEntry extends Omit<BoardPost, 'files'> {
3614
+ /** The board it is on, and its number there: together its reference. */
3615
+ node: NodePath;
3616
+ id: number;
3617
+ by: BoardAuthor;
3618
+ at: string;
3619
+ files?: BoardFile[];
3620
+ /** The branch `files` was read against, which is the same for every reader. */
3621
+ branch?: string;
3622
+ /** The entry it was raised from at a landing (R6), which keeps its author. */
3623
+ raisedFrom?: {
3624
+ node: NodePath;
3625
+ id: number;
3626
+ };
3627
+ }
3628
+ /** An entry as the log is told of it: the ledger numbers it and the clock stamps it. */
3629
+ type BoardDraft = Omit<BoardEntry, 'node' | 'id' | 'at'>;
3630
+
3631
+ /** `root/3/2`: the ids from the root down. A node's parent never changes, so neither does this. */
3632
+ type NodePath = string;
3633
+ interface OfNode {
3634
+ /** When it was written: for a reader, and never read by a fold. */
3635
+ at: string;
3636
+ node: NodePath;
3637
+ }
3638
+ type TreeFact = OfNode & (
3639
+ /** A node joined the tree. Below the root its `limit` is carved from its parent, and `kept` of it stays for the subplanner's next turn (ADR-0056 M5). */
3640
+ {
3641
+ kind: 'node_opened';
3642
+ sessionId: string;
3643
+ taskId?: string;
3644
+ limit: number;
3645
+ kept: number;
3646
+ }
3647
+ /** `node` confirmed closed: its parent holds its `limit` no longer, and is charged what it spent. */
3648
+ | {
3649
+ kind: 'node_closed';
3650
+ }
3651
+ /** Tokens as a runner or planner reported them. A turn spends what its node kept first. */
3652
+ | {
3653
+ kind: 'tokens_spent';
3654
+ tokens: number;
3655
+ turn?: true;
3656
+ taskId?: string;
3657
+ attempt?: number;
3658
+ }
3659
+ /** A raise: `tokens` more on `node`'s limit, from its parent's room. */
3660
+ | {
3661
+ kind: 'budget_raised';
3662
+ tokens: number;
3663
+ }
3664
+ /** Its parent's own spending took `tokens` of `node`'s room: `node`'s limit and its parent's `committed` fall together. */
3665
+ | {
3666
+ kind: 'budget_taken';
3667
+ tokens: number;
3668
+ }
3669
+ /** A subplanner parked, keeping `tokens` more for its next turn. */
3670
+ | {
3671
+ kind: 'reserve_kept';
3672
+ tokens: number;
3673
+ }
3674
+ /** The user set the root's limit, the tree's budget, to `limit`. */
3675
+ | {
3676
+ kind: 'limit_set';
3677
+ limit: number;
3678
+ }
3679
+ /** An entry on `node`'s board, whole: a board is a fold of these (ADR-0057 R8). */
3680
+ | {
3681
+ kind: 'board_posted';
3682
+ entry: BoardEntry;
3683
+ });
3684
+ /** A fact as the log holds it: `seq` is its place in the tree's one order, from 1. */
3685
+ type TreeEvent = TreeFact & {
3686
+ seq: number;
3687
+ };
3688
+
3689
+ /**
3690
+ * One append-only log per root (ADR-0058 S3), behind a port so that a daemon
3691
+ * host can back it with SQLite later. Only the host holding the root's session
3692
+ * lease writes it (ADR-0055 D13).
3693
+ */
3694
+ interface EventStore {
3695
+ /** In order, each batch whole: after a crash a reader finds all of a batch or none of it. Numbers them. */
3696
+ append(events: readonly TreeFact[]): Promise<void>;
3697
+ /** What came after the cursor, at `path` and below when one is named. */
3698
+ read(after: number, path?: NodePath): AsyncIterable<TreeEvent>;
3699
+ close(): Promise<void>;
3700
+ }
3701
+
3702
+ export { type InvokedCommand as $, AUTO_COMMANDS as A, type BashOptions as B, type CatalogModel as C, type CommandClassification as D, type CommandTier as E, ConsoleLogger as F, DENY_ALL as G, type DiscoveryCommand as H, type EditPlanArgs as I, type EventStore as J, type ExecutionBackend as K, type FetchAllProviderModelsOptions as L, type FindSymbolOptions as M, GIT_READONLY_SUBCOMMANDS as N, GREP_DEFAULT_HEAD_LIMIT as O, type GlobOptions as P, type GrepOptions as Q, type GrepOutputMode as R, type Guarantee as S, type GuaranteeReport as T, type IApproval as U, type IConfig as V, type IFileSystem as W, type ILogger as X, type INotification as Y, type IRunner as Z, type IRunnerSession as _, type AgentAdapter as a, type RunnerFeatures as a$, type IsolatedExecution as a0, IsolationRunController as a1, type LeaseRecord as a2, type LeaseRepo as a3, type LeaseRequest as a4, type LeaseSpec as a5, LineBuffer as a6, type ListModelsArgs as a7, type ListRunnersArgs as a8, type LoadSkillArgs as a9, type PlannerSandboxDeps as aA, PlannerShellSandbox as aB, type PlannerStartOptions as aC, type PlannerTokenScope as aD, type PlannerToolHandler as aE, type PostArgs as aF, type ProjectMcpServer as aG, type ProviderCredentialSource as aH, type ProviderModelLists as aI, type ProviderModelsResult as aJ, type QueuedTaskMessage as aK, READ_ONLY_TASK_TOOLS as aL, REFUSED_COMMANDS as aM, type ReadFileOpts as aN, type ReadTaskArgs as aO, type ResearchShell as aP, type ResearchShellDeps as aQ, type ReservedLease as aR, type RetryTaskArgs as aS, type RunCommandArgs as aT, type RunPlanArgs as aU, type RunnerAuthSpec as aV, type RunnerAuthStatus as aW, type RunnerCommand as aX, type RunnerCommandKind as aY, type RunnerEntry as aZ, type RunnerEnv as a_, type McpClientConfig as aa, type McpCredential as ab, type McpRefusal as ac, type McpTool as ad, type McpToolContext as ae, type McpToolReply as af, type MessageTaskArgs as ag, ModelCatalog as ah, type ModelShortcut as ai, type NodePath as aj, type NotificationAction as ak, ORCHESTRATOR_SHORTCUTS as al, ORDEWELL_MCP_PATH as am, ORDEWELL_MCP_SERVER_NAME as an, type OneTaskArgs as ao, type OpenLease as ap, type OrchestratorOption as aq, OrdewellMcpServer as ar, type OwnSealedRuns as as, type OwnerOnlyFile as at, PLANNER_EXECUTION_TOOLS as au, PLANNER_SANDBOX_DOCS as av, PLANNER_TOOLS as aw, type PlannerBackendId as ax, type PlannerModes as ay, type PlannerSandboxAvailability as az, type AgentAdapterFactory as b, fetchAllProviderModels as b$, type RunnerManifest as b0, type RunnerMcpServer as b1, type RunnerMode as b2, type RunnerModelDiscovery as b3, type RunnerModelRef as b4, type RunnerPlacement as b5, RunnerRegistry as b6, SEALED_LIMITS as b7, SEARCH_EXCLUSIONS as b8, type SandboxBackend as b9, type TaskMessageFrom as bA, type TaskModeAgentAdapter as bB, TaskModeUnsupportedError as bC, type TaskOutputArgs as bD, type TaskQueryArgs as bE, type TaskRunCommandArgs as bF, type TaskRunnerConfig as bG, type TaskRunnerFlags as bH, type TaskShell as bI, type TaskShellSite as bJ, type TaskStartOptions as bK, type TaskTokenScope as bL, type TaskToolHandler as bM, type TaskWebReads as bN, type ToolOutcome as bO, type TreeEvent as bP, type TreeFact as bQ, type UsageLimitSignal as bR, approvalScopes as bS, classifyCommand as bT, clearPlannerSandboxCache as bU, clearResearchShellCache as bV, collectProviderCredentials as bW, defaultLogger as bX, deleteSession as bY, effectiveApprovalMode as bZ, enabledRunners as b_, type SandboxInvocation as ba, type SandboxLaunch as bb, type SandboxLimits as bc, type SandboxProfile as bd, type ScriptExit as be, type ScriptFullOutput as bf, type ScriptRun as bg, type ScriptStatus as bh, type SealedAvailability as bi, type SealedRunOptions as bj, type SessionData as bk, type SessionMeta as bl, type ShellDialect as bm, type ShellLaunch as bn, type SkillLookup as bo, type SpawnFn as bp, type StandingDecision as bq, type StructuredEvent as br, type StructuredTurnEnd as bs, type SubmitPlanArgs as bt, TASK_COMPLETE_TOOL as bu, TASK_COMPLETION_CONTRACT as bv, TASK_SEALED_LIMITS as bw, TASK_TOOLS as bx, type TaskCompleteArgs as by, type TaskDiffArgs as bz, type AgentEvent as c, findRunnerCommand as c0, getLatestSession as c1, idSegment as c2, isGranted as c3, isRunnerApproval as c4, knownModelId as c5, listChildSessions as c6, listSessions as c7, loadChildSession as c8, loadSession as c9, loadSessionPlanState as ca, mcpClientConfig as cb, ownerOnlyConfigFile as cc, parseApprovalModeSetting as cd, plannerToolSet as ce, researchShellWarning as cf, researchToolsPath as cg, resolveModelShortcut as ch, resolvePlannerSandbox as ci, resolveProvider as cj, resolveResearchShell as ck, saveChildSession as cl, saveSession as cm, sessionDataDir as cn, sharedMcpServer as co, taskCompletionContract as cp, taskToolSet as cq, toApprovalDecision as cr, toOrchestratorOptions as cs, toolListing as ct, type AgentProcessDeps as d, type AgentStartOptions as e, type AiProvider as f, type AllProviderModels as g, type AnswerApprovalArgs as h, type ApplyPatchArgs as i, type ApprovalAnswer as j, type ApprovalDecision as k, type ApprovalKind as l, type ApprovalMode as m, type ApprovalModeSetting as n, ApprovalPolicy as o, type ApprovalPolicyOptions as p, type ApprovalRequest as q, type ApprovalSource as r, type AttachState as s, type BoardAuthor as t, type BoardDraft as u, type BoardEntry as v, type BoardPost as w, type CheckpointAnswer as x, type CheckpointArgs as y, type ChildSessionPlace as z };