@ordewell/core 0.11.2 → 0.12.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.
Files changed (42) hide show
  1. package/AUTHORS.md +3 -1
  2. package/dist/{IRunner-ihalYfTo.d.mts → IRunner-BwzyUVIL.d.mts} +62 -18
  3. package/dist/{IRunner-DOMtDTVt.d.ts → IRunner-DjJkYwko.d.ts} +62 -18
  4. package/dist/{ModeResolver-DyXeZ9ib.d.ts → ModeResolver-CHsaoV7M.d.ts} +1 -1
  5. package/dist/{ModeResolver-BDAgouuE.d.mts → ModeResolver-b_7bPlBS.d.mts} +1 -1
  6. package/dist/{Task-BL4Idm9r.d.mts → Task-BTEH-ztX.d.mts} +301 -26
  7. package/dist/{Task-BL4Idm9r.d.ts → Task-BTEH-ztX.d.ts} +301 -26
  8. package/dist/{chunk-MYXMIVWA.mjs → chunk-BFLVOYNR.mjs} +3 -3
  9. package/dist/{chunk-YAFNYNFX.mjs → chunk-BKTDYGIP.mjs} +14 -2
  10. package/dist/chunk-BKTDYGIP.mjs.map +1 -0
  11. package/dist/{chunk-QTZ5XTBY.mjs → chunk-F6WS3JLQ.mjs} +446 -10
  12. package/dist/chunk-F6WS3JLQ.mjs.map +1 -0
  13. package/dist/{chunk-7WNLN63J.mjs → chunk-HP2LNKST.mjs} +315 -51
  14. package/dist/chunk-HP2LNKST.mjs.map +1 -0
  15. package/dist/index.d.mts +242 -78
  16. package/dist/index.d.ts +242 -78
  17. package/dist/index.js +5598 -2005
  18. package/dist/index.js.map +1 -1
  19. package/dist/index.mjs +4701 -1782
  20. package/dist/index.mjs.map +1 -1
  21. package/dist/parsing.d.mts +2 -2
  22. package/dist/parsing.d.ts +2 -2
  23. package/dist/parsing.js.map +1 -1
  24. package/dist/parsing.mjs +3 -3
  25. package/dist/plan-utils.d.mts +4 -4
  26. package/dist/plan-utils.d.ts +4 -4
  27. package/dist/plan-utils.js +135 -19
  28. package/dist/plan-utils.js.map +1 -1
  29. package/dist/plan-utils.mjs +25 -3
  30. package/dist/{runSettingsText-CYMhTWfw.d.ts → runSettingsText-CvZ40IPv.d.ts} +1086 -190
  31. package/dist/{runSettingsText-tnmvdSfS.d.mts → runSettingsText-x-YML2ay.d.mts} +1086 -190
  32. package/dist/testing.d.mts +18 -2
  33. package/dist/testing.d.ts +18 -2
  34. package/dist/testing.js +71 -7
  35. package/dist/testing.js.map +1 -1
  36. package/dist/testing.mjs +68 -7
  37. package/dist/testing.mjs.map +1 -1
  38. package/package.json +2 -1
  39. package/dist/chunk-7WNLN63J.mjs.map +0 -1
  40. package/dist/chunk-QTZ5XTBY.mjs.map +0 -1
  41. package/dist/chunk-YAFNYNFX.mjs.map +0 -1
  42. /package/dist/{chunk-MYXMIVWA.mjs.map → chunk-BFLVOYNR.mjs.map} +0 -0
@@ -5,9 +5,14 @@ declare const SEVERITY_LABEL: Record<FindingSeverity, string>;
5
5
  declare function severityLabel(severity: FindingSeverity): string;
6
6
  /** The worst severity among `findings`, or null for none: what a compact row says at a glance. */
7
7
  declare function worstSeverity(findings: readonly Pick<HandoffFinding, 'severity'>[]): FindingSeverity | null;
8
+ /** The plan a pinned reference is under while every plan is the root's (ADR-0057 R1). */
9
+ declare const ROOT_NODE = "root";
8
10
  /**
9
11
  * A typed reference a reader can check rather than trust. A `task` names the
10
12
  * task by id once the call is accepted, and `finding` one of its findings.
13
+ * `node` and `attempt` pin it (ADR-0057 R1): F numbers restart per attempt, so
14
+ * a finding is named only with the attempt it belongs to. One saved before
15
+ * pinning has neither, and reads the latest attempt as it always did.
11
16
  * `resolved` is read-time metadata: the author cannot vouch for resolution,
12
17
  * so the completion schema strips it and the saved handoff carries no check.
13
18
  */
@@ -23,7 +28,9 @@ type HandoffEvidence = {
23
28
  resolved?: boolean;
24
29
  } | {
25
30
  kind: 'task';
31
+ node?: string;
26
32
  task: string;
33
+ attempt?: number;
27
34
  finding?: string;
28
35
  } | {
29
36
  kind: 'url';
@@ -93,6 +100,8 @@ interface HandoffDigest {
93
100
  findings: HandoffFinding[];
94
101
  findingCount: number;
95
102
  artifacts?: HandoffArtifact[];
103
+ /** The attempt it is from, which a reference to it is pinned to (ADR-0057 R1); absent on a plan saved before it was kept. */
104
+ attempt?: number;
96
105
  }
97
106
  /** The whole handoff, as the attempt's log keeps it. */
98
107
  interface StoredHandoff extends HandoffDigest {
@@ -144,7 +153,43 @@ declare function handoffDigest(handoff: StoredHandoff): HandoffDigest;
144
153
  type HandoffTaskName = (taskId: string) => string | undefined;
145
154
  /** A handoff with the tasks it cites named by their references in `plan`, as a reader names them. */
146
155
  declare function namedHandoff<H extends HandoffDigest>(plan: readonly Task[], handoff: H): H;
147
- /** A typed reference as a reader says it: `src/a.ts:42`, `commit abc`, `task #2 F1`, a URL, a saved patch. */
156
+ /** A task reference as a reader writes it and an author may: `#4@2/F3`, `#4/F3`, `#4@2` or `#4` (ADR-0057 R1). */
157
+ interface WrittenTaskRef {
158
+ task: string;
159
+ attempt?: number;
160
+ finding?: string;
161
+ }
162
+ /**
163
+ * The parts of a written reference, its task as written. What this cuts off
164
+ * is no part of `TaskRefs`' grammar, which stays as it was; a caller tries the
165
+ * text whole first, since a title may end in anything.
166
+ */
167
+ declare function parseFindingRef(written: string): WrittenTaskRef;
168
+ /**
169
+ * A written reference resolved in a plan, its pin apart. The text is tried
170
+ * whole first: a title may end in anything, and a task it names stands as it
171
+ * always did. Undefined when it names no task there.
172
+ */
173
+ declare function resolveWrittenRef(plan: readonly Task[], written: string): (Omit<WrittenTaskRef, 'task'> & {
174
+ task: Task;
175
+ }) | undefined;
176
+ /**
177
+ * The attempt of a removed task a reference naming no task in the plan reaches,
178
+ * by the id it renders with: a removed task keeps its log (ADR-0057 R1). The
179
+ * graph no longer reaches that task, so a citation does: a handoff in the
180
+ * reader's readable set must cite the attempt, since a task cannot read work it
181
+ * was never given (ADR-0047). A citation saved unpinned cites the latest, and a
182
+ * reference naming no attempt takes the newest one cited. `asked` is an attempt
183
+ * given apart from the text. Undefined when nothing it may read cites one.
184
+ */
185
+ declare function removedAttempt(plan: readonly Task[], readerId: string, logs: HandoffLogs, written: string, asked?: number): {
186
+ taskId: string;
187
+ attempt: number;
188
+ finding?: string;
189
+ } | undefined;
190
+ /** The pinned reference as text: `#4@2/F3` (ADR-0057 R1); `task` is how the reader names it. */
191
+ declare function findingRefText(task: string, ref: Pick<WrittenTaskRef, 'attempt' | 'finding'>): string;
192
+ /** A typed reference as a reader says it: `src/a.ts:42`, `commit abc`, `#2@1/F1`, a URL, a saved patch. */
148
193
  declare function handoffReferenceText(ref: HandoffArtifact, taskName?: HandoffTaskName): string;
149
194
  /** A size as a reader takes it in: bytes, KB or MB. */
150
195
  declare function byteSize(bytes: number): string;
@@ -197,6 +242,12 @@ declare function findingLines(f: HandoffFinding, taskName?: HandoffTaskName): st
197
242
  declare function artifactLines(handoff: HandoffDigest, taskName?: HandoffTaskName): string[];
198
243
  /** A handoff's opening as text: its commit, subject then body, then the summary. */
199
244
  declare function openingLines(handoff: HandoffDigest): string[];
245
+ /**
246
+ * How another task's words are introduced wherever they cross into a prompt
247
+ * or a run update (ADR-0057 R3): whose they are, and that they are data. On
248
+ * every wake and every dependency, so it stays this short.
249
+ */
250
+ declare function wordsFrom(what: string, whose: string): string;
200
251
  /** Each pushed handoff's text ceiling, excluding artifacts (ADR-0047). */
201
252
  declare const HANDOFF_PUSH_CHARS = 4000;
202
253
  /** Shared push rendering: reserve the closing pointer before accepting each whole finding. */
@@ -239,15 +290,33 @@ type HandoffCheck<H> = {
239
290
  ok: false;
240
291
  refusal: string;
241
292
  };
293
+ /** What the session's saved logs say of a task's attempts, for a reference to be pinned against (ADR-0057 R1). */
294
+ interface HandoffLogs {
295
+ /** The attempts of a task that have a saved log, oldest first. */
296
+ attempts(taskId: string): readonly number[];
297
+ /** The handoff one attempt ended with, if its log holds one. */
298
+ handoff(taskId: string, attempt: number): HandoffDigest | undefined;
299
+ }
300
+ interface HandoffPins {
301
+ /** The saved logs; without them a reference pins to what the plan's digest says, or stays unpinned. */
302
+ logs?: HandoffLogs;
303
+ /** The attempt making the call: what a task naming itself is pinned to. */
304
+ attempt?: number;
305
+ }
242
306
  /**
243
307
  * Check the references a handoff makes, at the call (ADR-0047): a `task`
244
308
  * must be one the producer may read and a finding of it one that exists, and
245
309
  * a `url` must be http or https, so no surface renders a `javascript:` link.
246
310
  * A `file` or `commit` is a claim about a tree Ordewell may not see, so it is
247
311
  * taken as given. An accepted handoff names each task by its id, which a
248
- * later edit of the plan does not renumber.
249
- */
250
- declare function checkHandoff<H extends Handoff>(handoff: H, producerId: string, plan: readonly Task[]): HandoffCheck<H>;
312
+ * later edit of the plan does not renumber, and the attempt it read, so a
313
+ * retry or a loop round that numbers its findings anew leaves it meaning what
314
+ * it meant (ADR-0057 R1). A task with nothing to say its attempt by stays
315
+ * unpinned, and reads the latest, as a reference saved before pinning does. A
316
+ * removed task may be cited where a handoff the producer may read cites it, so
317
+ * what it read can be passed on ({@link removedAttempt}).
318
+ */
319
+ declare function checkHandoff<H extends Handoff>(handoff: H, producerId: string, plan: readonly Task[], pins?: HandoffPins): HandoffCheck<H>;
251
320
 
252
321
  interface TaskDiffRead {
253
322
  repo?: string;
@@ -445,10 +514,12 @@ interface IsolationTaskRecord {
445
514
  */
446
515
  readOnly?: true;
447
516
  /**
448
- * Set once the task's landed work is in the checked-out HEAD of every repo
449
- * it changed — merged into the user's branch, by Merge all or by hand — or
450
- * can no longer be merged there, its integration branch gone. What a merge
451
- * gate waits for (ADR-0020).
517
+ * Set once the task's landed work is merged into the user's branch in every
518
+ * repo it landed in, by Merge all or by hand — never by a checkout that only
519
+ * stands on the integration branch (ADR-0054) — or can no longer be merged
520
+ * there, its integration branch gone. What a merge gate waits for (ADR-0020).
521
+ * Git's answer as last read, so it goes when the user takes the merge back
522
+ * out; it goes with the record too, so a revert asks git of each merge instead.
452
523
  */
453
524
  inHead?: true;
454
525
  }
@@ -462,6 +533,16 @@ interface IsolationLanding {
462
533
  taskId: string;
463
534
  /** Keyed by repo path. */
464
535
  tips: Record<string, string>;
536
+ /**
537
+ * Set when this is a revert rather than a landing (ADR-0054), by repo path:
538
+ * what a rollback has to find on that repo's tip to take it off again.
539
+ */
540
+ reverts?: Record<string, IsolationRepoRevert>;
541
+ }
542
+ /** A revert's share of one repo, saved so that it can tell its own commits from anyone else's. */
543
+ interface IsolationRepoRevert {
544
+ /** The commits it has made, oldest first, each saved before the branch moves onto it. */
545
+ commits: string[];
465
546
  }
466
547
  /**
467
548
  * One repository of the group (ADR-0014). Every git operation on it runs in
@@ -511,6 +592,51 @@ interface IsolationRun {
511
592
  * names exactly what to return each repo's integration branch to.
512
593
  */
513
594
  landing?: IsolationLanding;
595
+ /**
596
+ * Every merge that landed a task, by task id and repo, oldest first. A
597
+ * continue or a retry lands a task again under a new record, so no record
598
+ * holds them all, and a revert takes them all back (ADR-0054). A run saved
599
+ * before these were kept has only each record's `landedTip`.
600
+ */
601
+ landings?: Record<string, Record<string, string[]>>;
602
+ /**
603
+ * Set on a run started with {@link landings} kept from its first merge. A
604
+ * run saved before that can hold merges no record names, so a revert cannot
605
+ * take the absence of a task's landings as proof it landed nothing.
606
+ */
607
+ keepsEveryLanding?: true;
608
+ /**
609
+ * Task branch tips another task's merge brought in, by task id and repo: a
610
+ * resolver's merge carrying a conflicted task's work. No merge of that task
611
+ * holds this work, and a later attempt's record says nothing of it, so
612
+ * neither task can be reverted (ADR-0054). A tip git could not say of when
613
+ * that merge landed is here too. Set on every run as it starts, empty
614
+ * included: a run without it is older, what its merges carried is unknown,
615
+ * and every revert of it is refused.
616
+ */
617
+ carried?: Record<string, Record<string, string[]>>;
618
+ /**
619
+ * What each task in {@link landings} or {@link carried} landed as: all a
620
+ * revert has to name it by once a retry has dropped its record and left its
621
+ * merges on the branch.
622
+ */
623
+ landedTasks?: Record<string, LandedTask>;
624
+ /**
625
+ * What each task depended on when its worktree was cut and when it landed,
626
+ * directly or not, by task id, across every attempt. A plan edit takes a link
627
+ * while a worktree stays cut from what it stood on, and leaving the plan takes
628
+ * a task's dependencies with it, and those of the tasks that named it, while
629
+ * its merges stay on the branch, so this is what finds a dependent the plan
630
+ * has lost, at work or landed. A landed task the plan no longer has and this
631
+ * does not name refuses every revert of the run (ADR-0054).
632
+ */
633
+ landedOn?: Record<string, string[]>;
634
+ /**
635
+ * A task's revert was committed on this run (ADR-0054): the integration
636
+ * branch holds commits no record names, so the run carries on even with no
637
+ * record left, and a retry starts from its tip.
638
+ */
639
+ reverted?: true;
514
640
  }
515
641
  /**
516
642
  * What a plan persists of isolated execution (`LegacyPlanState.isolation`): its
@@ -530,8 +656,13 @@ interface PlanIsolation {
530
656
  * that has an isolation run.
531
657
  */
532
658
  type TaskIsolationState = 'none' | 'active' | 'integrated' | 'conflict' | 'repairing' | 'kept';
533
- type TaskIsolation = {
659
+ /** What a conflict repair that will start by itself waits for (ADR-0015). */
660
+ type RepairWait = 'slot' | 'planner' | 'usage-limit';
661
+ type TaskIsolation =
662
+ /** `revertible`: no record, but merges of an earlier attempt are still on the branch. */
663
+ {
534
664
  state: 'none';
665
+ revertible?: true;
535
666
  } | {
536
667
  state: Exclude<TaskIsolationState, 'none'>;
537
668
  branch: string;
@@ -549,6 +680,12 @@ type TaskIsolation = {
549
680
  };
550
681
  /** What {@link IsolationTaskRecord.repairedFiles} says. */
551
682
  repairedFiles?: string[];
683
+ /** Its landing has a merge of its own and is not in the user's branch: what a surface offers a revert on (ADR-0054). */
684
+ revertible?: true;
685
+ /** A `conflict` whose repair starts by itself once this clears: progress, not a conflict to act on (ADR-0015). Said by the scheduler, not the record. */
686
+ repairWaits?: RepairWait;
687
+ /** A `conflict` a task was added to resolve, by id: its one worker (ADR-0015). */
688
+ resolver?: string;
552
689
  };
553
690
  interface IsolationLandedTask {
554
691
  taskId: string;
@@ -693,6 +830,87 @@ type PreviousWork = {
693
830
  };
694
831
  /** A task as a removal names it. */
695
832
  type IsolationTaskRef = Pick<IsolationTaskRecord, 'taskId' | 'order' | 'title'>;
833
+ /** A task as its landings name it, and what the commit that reverts one is worded from. */
834
+ type LandedTask = IsolationTaskRef & Pick<IsolationTaskRecord, 'commit'>;
835
+ /** A task a revert acts on, with the repos its landing changed. */
836
+ interface IsolationRevertTask extends IsolationTaskRef {
837
+ repos: string[];
838
+ }
839
+ /**
840
+ * What undoes a task's landing once something of the user's holds it: a command
841
+ * for them to run, which Ordewell shows and never runs (ADR-0054).
842
+ */
843
+ interface RevertCommand {
844
+ task: IsolationTaskRef;
845
+ repo: string;
846
+ /** The task's merge commit, which `heldBy` holds. */
847
+ commit: string;
848
+ /** Ready to type at the workspace root. */
849
+ command: string;
850
+ /** What holds it and stops a revert: local branches by name, and 'HEAD' for a detached HEAD. */
851
+ heldBy: string[];
852
+ /** Whether the user's own branch is among them; if not, `heldBy` may be only a review. */
853
+ merged: boolean;
854
+ }
855
+ /**
856
+ * What git says of the landed work a revert would take, newest landing first.
857
+ * `inBranch`: the part something of the user's holds, which no revert touches;
858
+ * newest first too, the order to run the commands in. `no-own-merge`: a task's
859
+ * work came in through another's merge, a conflict resolver's, so no merge of
860
+ * its own can undo it. `git`: git could not read what the record names, or say
861
+ * what holds it.
862
+ */
863
+ type LandedWork = {
864
+ ok: true;
865
+ tasks: IsolationRevertTask[];
866
+ inBranch: RevertCommand[];
867
+ } | {
868
+ ok: false;
869
+ reason: 'no-own-merge' | 'checked-out' | 'git';
870
+ error: string;
871
+ };
872
+ /** What {@link IWorktreeIsolation.revert} asks of its caller, in its turn. */
873
+ interface RevertWatch {
874
+ /** Why the revert may no longer go ahead, read once it has its turn and again with its commits made, which it then rolls back; null when it may. */
875
+ refusal: () => string | null;
876
+ /** Called once the tips are recorded and before the first commit, as a landing's `persist` is, and again as each commit is made. */
877
+ persist: () => void;
878
+ /** Called in the one synchronous step that lets the records go, so a save never sees them gone with the tasks not yet back. */
879
+ settled: (taskIds: readonly string[]) => void;
880
+ }
881
+ /**
882
+ * How a revert ended (ADR-0054). Anything but `reverted` left every integration
883
+ * branch where it was, except a `failed` that says so: tips git would not put
884
+ * back stay recorded on the run, which holds landings and Merge all off them.
885
+ *
886
+ * - `reverted`: `tasks`, newest landing first, in every repo each changed.
887
+ * - `in-branch`: something of the user's holds part of it: `commands` undo it there.
888
+ * - `refused`: {@link RevertWatch.refusal} said no, or git found work with no
889
+ * merge of its own, or the integration branch checked out where a revert
890
+ * cannot commit to it.
891
+ * - `conflict`: reverting `task` conflicted in `repo`, over `files`.
892
+ * - `failed`: git stopped it; `error` says on what.
893
+ */
894
+ type IsolationRevertResult = {
895
+ outcome: 'reverted';
896
+ tasks: IsolationRevertTask[];
897
+ } | {
898
+ outcome: 'in-branch';
899
+ commands: RevertCommand[];
900
+ } | {
901
+ outcome: 'refused';
902
+ reason: string;
903
+ } | {
904
+ outcome: 'conflict';
905
+ task: IsolationTaskRef;
906
+ repo: string;
907
+ files: string[];
908
+ } | {
909
+ outcome: 'failed';
910
+ error: string;
911
+ task?: IsolationTaskRef;
912
+ repo?: string;
913
+ };
696
914
  /**
697
915
  * Work a removal found that had not landed — edits never committed, or
698
916
  * commits only the task's branch carried — committed and kept on `branch`,
@@ -806,6 +1024,22 @@ interface IWorktreeIsolation {
806
1024
  * the runner made is never rewritten.
807
1025
  */
808
1026
  integrate(task: Task, run: IsolationRun, persist?: () => void, commit?: HandoffCommit): Promise<IsolationOutcome>;
1027
+ /**
1028
+ * What git says of the tasks' landed work now. Reads only and takes no turn:
1029
+ * it answers a confirmation, and {@link revert} reads it all again in its own.
1030
+ */
1031
+ readLanded(run: IsolationRun, taskIds: readonly string[]): Promise<LandedWork>;
1032
+ /**
1033
+ * Revert the tasks' landings on the integration branches (ADR-0054): one
1034
+ * revert commit per landing, newest first, in every repo each changed or in
1035
+ * none. Takes its turn on the landing queue, so it never reads
1036
+ * a branch mid-landing, judges what it is asked again there, and writes only
1037
+ * to Ordewell's own branches. Each reverted task's record goes: its landing
1038
+ * no longer counts for anything. A record of a later attempt that did not
1039
+ * land stays for the worktree it holds, kept like a stopped one's. What
1040
+ * stops it puts every tip back.
1041
+ */
1042
+ revert(run: IsolationRun, taskIds: readonly string[], watch: RevertWatch): Promise<IsolationRevertResult>;
809
1043
  /**
810
1044
  * `keep: false` removes the task's worktree, branch and record (retry, task
811
1045
  * removal), keeping whatever had not landed on a branch first; a record
@@ -838,11 +1072,12 @@ interface IWorktreeIsolation {
838
1072
  reviewDiff(run: IsolationRun): Promise<string>;
839
1073
  taskDiff?(run: IsolationRun, taskId: string, options: TaskDiffRead): Promise<TaskDiffResult>;
840
1074
  /**
841
- * Mark the landed tasks whose work the checked-out HEAD now contains in
842
- * every repo they changed (`git merge-base --is-ancestor`), and return their
843
- * ids. A repo whose integration branch is gone counts as containing it: no
844
- * Merge all could bring that work in. Only adds marks: a task found merged
845
- * stays merged.
1075
+ * Read each landed task's mark again from git: on where the user's branch
1076
+ * contains its work in every repo it changed (`git merge-base --is-ancestor`),
1077
+ * off where it no longer does. Returns the ids whose mark changed. A review
1078
+ * checkout of the integration branch, detached or not, contains nothing
1079
+ * merged (ADR-0054). A repo whose integration branch is gone counts as
1080
+ * containing it: no Merge all could bring that work in.
846
1081
  */
847
1082
  findInHead(run: IsolationRun): Promise<string[]>;
848
1083
  /**
@@ -1153,7 +1388,7 @@ type SupervisorLevel = 'off' | 'watch' | 'act';
1153
1388
  declare function isSupervisorLevel(value: unknown): value is SupervisorLevel;
1154
1389
  /**
1155
1390
  * Who asked the command seam for an action (ADR-0029): the user, a planner
1156
- * turn the user started, or the supervisor at its level.
1391
+ * turn the user started, the supervisor at its level, autorun, or a subplanner.
1157
1392
  */
1158
1393
  type ExecutionActor = {
1159
1394
  kind: 'user';
@@ -1163,15 +1398,23 @@ type ExecutionActor = {
1163
1398
  kind: 'supervisor';
1164
1399
  level: SupervisorLevel;
1165
1400
  }
1166
- /** The user's standing instruction to start each plan the planner submits (ADR-0030). */
1401
+ /** The user's standing instruction to start each plan the planner submits (ADR-0030); `leavesFailed` is what failed in that reply, which it does not run again. */
1167
1402
  | {
1168
1403
  kind: 'autorun';
1404
+ leavesFailed?: ReadonlySet<string>;
1405
+ }
1406
+ /** Every turn of a child plan's planner (ADR-0056 M6): no person is there, so its grants alone answer. `depth` is its level, the root being 0. */
1407
+ | {
1408
+ kind: 'subplanner';
1409
+ depth: number;
1169
1410
  };
1170
- type ExecutionCommandName = 'run_plan' | 'run_task' | 'stop_task' | 'stop_run' | 'retry_task' | 'message_task' | 'answer_approval' | 'merge_all' | 'skip_task' | 'force_start' | 'mark_complete' | 'mark_not_done' | 'interrupt_task' | 'force_send_queued' | 'remove_queued' | 'cancel_resume' | 'answer_checkpoint' | 'approve_review' | 'run_script';
1411
+ /** Whose authority an actor's work runs under: a child has no user, so a subplanner's is a supervisor's (ADR-0056 M6). */
1412
+ declare function actorAuthority(actor: ExecutionActor['kind']): TurnAuthority;
1413
+ type ExecutionCommandName = 'run_plan' | 'run_task' | 'stop_task' | 'stop_run' | 'retry_task' | 'message_task' | 'answer_approval' | 'merge_all' | 'skip_task' | 'force_start' | 'mark_complete' | 'mark_not_done' | 'revert_task' | 'interrupt_task' | 'force_send_queued' | 'remove_queued' | 'cancel_resume' | 'answer_checkpoint' | 'approve_review' | 'run_script';
1171
1414
  /**
1172
1415
  * How the user consented to the script a `run_script` call ran (ADR-0035):
1173
1416
  * on the approval card, by an effect allowlist rule (by name), by autorun in
1174
- * Full, or by choosing Act for the supervisor.
1417
+ * Full, by choosing Act for the supervisor, or by a subplanner's mandate.
1175
1418
  */
1176
1419
  type ScriptConsent = {
1177
1420
  by: 'card';
@@ -1182,6 +1425,8 @@ type ScriptConsent = {
1182
1425
  by: 'autorun';
1183
1426
  } | {
1184
1427
  by: 'act';
1428
+ } | {
1429
+ by: 'mandate';
1185
1430
  };
1186
1431
  /**
1187
1432
  * Where a `run_script` call's task stood as the call answered, or as it ended
@@ -1423,6 +1668,8 @@ interface SupervisionMemorySnapshot {
1423
1668
  edits: EditMemory;
1424
1669
  /** The keys of the guard trips the user was already told of. */
1425
1670
  told: string[];
1671
+ /** The tasks the user stopped and has not started again. Absent on saves before it. */
1672
+ stopped?: string[];
1426
1673
  }
1427
1674
  /** What the supervisor's own edits did this run: the tasks it removed, and each field it changed. */
1428
1675
  interface EditMemory {
@@ -1438,14 +1685,18 @@ interface EditMemory {
1438
1685
  }
1439
1686
 
1440
1687
  /**
1441
- * When the supervisor wakes during a run, and what it is told (#27). Only an
1442
- * attention event wakes it; passes ride along as context. It keeps no clock:
1443
- * the host stamps each event and polls on its own tick.
1688
+ * When the supervisor wakes during a run (#27, ADR-0057 R4). The decision is
1689
+ * {@link wakeDue}, a pure function of the events held and what the plan says:
1690
+ * no model, and no clock of its own, since the host stamps each event and polls
1691
+ * on its own tick. A pass opens nothing and rides along as context. An event a
1692
+ * person or a planner is waiting on wakes at once, which is ADR-0029's merge
1693
+ * window. Anything else is held until the plan says it is time, or until the
1694
+ * planner's prompt cache would go cold.
1444
1695
  *
1445
1696
  * `task_report` is a task addressed to the planner ending: one whose result a
1446
1697
  * planner turn asked for and did not get before it answered (ADR-0037, R2).
1447
- * It is batched as any attention event is, and wakes the planner whatever the
1448
- * supervisor's level, since the planner asked for it.
1698
+ * It wakes the planner whatever the supervisor's level, since the planner
1699
+ * asked for it.
1449
1700
  */
1450
1701
  type RunEventKind = 'task_passed' | 'task_failed' | 'waiting_input' | 'waiting_approval' | 'task_idle' | 'landing_conflict' | 'usage_limit' | 'auto_merge_stopped' | 'run_finished' | 'task_report';
1451
1702
  type RunEvent = {
@@ -1473,7 +1724,7 @@ interface TaskReportEvent {
1473
1724
  }
1474
1725
  /** What the policy holds before its next wake-up, for the plan (ADR-0029). */
1475
1726
  interface WakePolicySnapshot {
1476
- /** Attention events inside the debounce window, in arrival order. */
1727
+ /** The events waiting for a wake-up, in arrival order. */
1477
1728
  attention: RunEvent[];
1478
1729
  /** The passes since the previous wake-up. */
1479
1730
  sinceLast: RunEvent[];
@@ -1490,6 +1741,8 @@ interface SupervisorSnapshot {
1490
1741
  policy: WakePolicySnapshot;
1491
1742
  /** When each wake-up since the last pass was delivered, for the wake-up rate guard. */
1492
1743
  wakeUps: number[];
1744
+ /** The user's Stop stands: a reload is not them starting the run again (ADR-0029). */
1745
+ stopped?: true;
1493
1746
  }
1494
1747
 
1495
1748
  interface UserStep {
@@ -1520,7 +1773,8 @@ interface Verdict {
1520
1773
  * `done` on exit 0, `failed` on a non-zero exit, a signal or its time limit,
1521
1774
  * `blocked` when it could not start. A loop starts a round only on `failed`
1522
1775
  * (ADR-0045 L2). Absent when nothing reported: a runner that exited without
1523
- * the call, Mark complete, a stopped script, a verdict saved before it was kept.
1776
+ * the call, Mark complete, a stopped script, an attempt the host died in, a
1777
+ * verdict saved before it was kept.
1524
1778
  */
1525
1779
  reported?: 'done' | 'failed' | 'blocked';
1526
1780
  }
@@ -1615,6 +1869,13 @@ interface Task {
1615
1869
  runnerSessionOwner?: RunnerId;
1616
1870
  /** Set only while `status` is `awaiting_user`, and not always then — a pause saved by an older build has none. */
1617
1871
  awaitingReason?: AwaitingReason;
1872
+ /**
1873
+ * How many waits have ended since its latest attempt started, or since the
1874
+ * task was written if none has: an attempt can wait many times, and this
1875
+ * tells one wait from the next in an escalation's id (ADR-0053). Saved with
1876
+ * the plan, so the id holds across a reload. Absent counts as none.
1877
+ */
1878
+ waitsEnded?: number;
1618
1879
  /**
1619
1880
  * When a task paused on its runner's usage limit is resumed on its own (ISO
1620
1881
  * time): the reset the runner announced, plus a short margin. Absent when no
@@ -1630,6 +1891,12 @@ interface Task {
1630
1891
  carriedFrom?: RunnerId;
1631
1892
  /** Why the task was skipped, as whoever skipped it put it; set only while `status` is `skipped`, and not always then. */
1632
1893
  skipReason?: string;
1894
+ /**
1895
+ * The user reverted its landed work (ADR-0054): saved with the plan, so the
1896
+ * hold that keeps it from running again outlives this process. Set only
1897
+ * while it waits as the revert left it: its next start clears it.
1898
+ */
1899
+ reverted?: true;
1633
1900
  /**
1634
1901
  * An ops task (ADR-0020): it changes no repository files, runs at the
1635
1902
  * workspace root rather than in a worktree, and waits for the change tasks
@@ -1709,6 +1976,9 @@ type TaskReportTo = ({
1709
1976
  } | {
1710
1977
  actor: 'supervisor';
1711
1978
  level: SupervisorLevel;
1979
+ } | {
1980
+ actor: 'subplanner';
1981
+ depth: number;
1712
1982
  });
1713
1983
  /** Whose authority a turn opened without the user acts with (ADR-0037, R3): the user's turn, or the supervisor's. */
1714
1984
  type TurnAuthority = 'user' | 'supervisor';
@@ -1995,6 +2265,11 @@ interface PendingPlanTurn {
1995
2265
  * the user's turn, which the turn then acts as (R3).
1996
2266
  */
1997
2267
  report?: TurnAuthority;
2268
+ /**
2269
+ * The tasks a supervisor input is wholly about, absent when any of it is about
2270
+ * the run. While the user has stopped all of them it opens no turn (ADR-0029).
2271
+ */
2272
+ tasks?: string[];
1998
2273
  }
1999
2274
  /**
2000
2275
  * The run's own copy of the user's run settings (ADR-0030): taken when the
@@ -2192,4 +2467,4 @@ type ApprovalRecord = Pick<LegacyPlanState, 'approved' | 'approvedTasks'>;
2192
2467
  */
2193
2468
  declare function waitsForApproval(task: Pick<Task, 'id' | 'type' | 'status'>, record: ApprovalRecord): boolean;
2194
2469
 
2195
- export { type IsolationTaskStatus as $, type ApprovalRecord as A, BUILTIN_SKILL_NAMES as B, type ContextCheckpoint as C, DEFAULT_LOOP_ROUNDS as D, type ExecutionActor as E, type FindingSeverity as F, type GuardTarget as G, HANDOFF_LIMITS as H, type IIsolationPreview as I, type IsolationAvailability as J, type IsolationHandoff as K, type IsolationHandoffRepo as L, type IsolationInactiveReason as M, type IsolationLandedTask as N, type IsolationLanding as O, type IsolationMergeBlock as P, type IsolationMergeBlockReason as Q, type IsolationMergeResult as R, type IsolationOutcome as S, type IsolationPreview as T, type IsolationPruneResult as U, type IsolationRemoval as V, type IsolationRepo as W, type IsolationRun as X, type IsolationTaskRecord as Y, type IsolationTaskRef as Z, type IsolationTaskRepo as _, type AttemptUsage as a, type TaskSkillSnapshot as a$, type IsolationView as a0, type LegacyPlanState as a1, type LoopSubject as a2, MAX_LOOP_ROUNDS as a3, type ModelUsage as a4, type PatchFlag as a5, type PatchView as a6, type PendingPlanTurn as a7, type PlanIsolation as a8, type PlanState as a9, type RunnerSessionCost as aA, SEVERITY_LABEL as aB, type ScriptConsent as aC, type ScriptResult as aD, type SessionBilling as aE, type SetupFailure as aF, type ShadowedSkill as aG, type SkillAppliesTo as aH, type SkillCatalog as aI, type SkillInfo as aJ, type SkillLoad as aK, type SkillLoadNotice as aL, type SkillMetadata as aM, type SkillSource as aN, SkillsService as aO, type StoredHandoff as aP, type SubagentOutcome as aQ, type SupervisorLevel as aR, type Task as aS, type TaskDiffRead as aT, type TaskDiffResult as aU, type TaskIsolation as aV, type TaskIsolationState as aW, type TaskLoop as aX, type TaskModelAssignment as aY, type TaskReportTo as aZ, type TaskSkillNotice as a_, type PlanStatus as aa, type PlanUsage as ab, type PlannerCompaction as ac, type PlannerCompactionOutcome as ad, type PlannerContextPause as ae, type PlannerResendState as af, type PlannerUsage as ag, type PrepareIntent as ah, type PreparedTask as ai, type PreservedWork as aj, type PreviewRepo as ak, type PreviousWork as al, REPORT_MAX_CHARS as am, type RefusedRemoval as an, type RepairEvidence as ao, type ReplyRun as ap, type RepoGroupLayout as aq, type RepoHead as ar, type ReportedWindow as as, type ResearchLogEntry as at, type ResearchProgress as au, type ResearchStep as av, type ResearchStepOutcome as aw, type ResearchToolType as ax, type RunSettings as ay, type RunnerId as az, type AwaitingReason as b, resumedSessionWindow as b$, type TaskSnapshot as b0, type TaskStatus as b1, type TaskType as b2, type TaskUsageSummary as b3, type TreeSnapshot as b4, type UsageLine as b5, type UsageRecord as b6, type UsageTotals as b7, type Verdict as b8, type VerificationCheck as b9, handoffPreviewLines as bA, handoffReferenceText as bB, handoffWakeLines as bC, inLoop as bD, isAwaitingReason as bE, isMeasured as bF, isSupervisorLevel as bG, isUserMessage as bH, loopRemovalRefusal as bI, loopRoundOf as bJ, migratePlanState as bK, modelCostTitle as bL, namedHandoff as bM, openingLines as bN, outOfRounds as bO, partedPromptUsage as bP, patchChangesText as bQ, patchFlagText as bR, patchLines as bS, patchLinesText as bT, patchText as bU, patchView as bV, pausedOnLimit as bW, planUsage as bX, plannerContextFill as bY, readableTaskIds as bZ, rejoinPlanTree as b_, addAttemptUsage as ba, addModelUsage as bb, addPlannerUsage as bc, addUsage as bd, addUsageTotals as be, artifactLines as bf, betweenRounds as bg, boundedHandoffLines as bh, byteSize as bi, checkHandoff as bj, checkOf as bk, contextMeterText as bl, contextMeterTitle as bm, costText as bn, countedSessionCost as bo, createEmptyPlan as bp, createSkillsService as bq, createTask as br, endAttemptUsage as bs, findingLines as bt, flattenTasks as bu, flattenTasksWithParents as bv, formatCost as bw, formatTokenCount as bx, handoffDigest as by, handoffLines as bz, type ContextFill as c, savedPatchOf as c0, savedPatchView as c1, savedPatchViews as c2, severityLabel as c3, startAttemptUsage as c4, storedHandoff as c5, subagentCostTitle as c6, taskUsageSummary as c7, tasksTotalText as c8, usageLine as c9, usageText as ca, waitsForApproval as cb, withPatch as cc, worstSeverity as cd, type ConversationMessage as d, type CostProvenance as e, DEFAULT_RUNNERS as f, DEFAULT_SUPERVISOR_RETRY_LIMIT as g, DIGEST_FINDINGS as h, type DiscoveredModel as i, type ExecutionCommandName as j, type ExecutionRecord as k, type GuardTrip as l, HANDOFF_PUSH_CHARS as m, type Handoff as n, type HandoffArtifact as o, type HandoffCheck as p, type HandoffCommit as q, type HandoffDigest as r, type HandoffEvidence as s, type HandoffFinding as t, type HandoffPatch as u, type HandoffPreviewOptions as v, type HandoffTaskName as w, type IWorktreeIsolation as x, type IntegrationDisposal as y, type InvalidSkill as z };
2470
+ export { type IsolationRevertTask as $, type ApprovalRecord as A, BUILTIN_SKILL_NAMES as B, type ContextCheckpoint as C, DEFAULT_LOOP_ROUNDS as D, type ExecutionActor as E, type FindingSeverity as F, type GuardTarget as G, HANDOFF_LIMITS as H, type IIsolationPreview as I, type IntegrationDisposal as J, type InvalidSkill as K, type IsolationAvailability as L, type IsolationHandoff as M, type IsolationHandoffRepo as N, type IsolationInactiveReason as O, type IsolationLandedTask as P, type IsolationLanding as Q, type IsolationMergeBlock as R, type IsolationMergeBlockReason as S, type IsolationMergeResult as T, type IsolationOutcome as U, type IsolationPreview as V, type IsolationPruneResult as W, type IsolationRemoval as X, type IsolationRepo as Y, type IsolationRepoRevert as Z, type IsolationRevertResult as _, type AttemptUsage as a, type SubagentOutcome as a$, type IsolationRun as a0, type IsolationTaskRecord as a1, type IsolationTaskRef as a2, type IsolationTaskRepo as a3, type IsolationTaskStatus as a4, type IsolationView as a5, type LandedTask as a6, type LandedWork as a7, type LegacyPlanState as a8, type LoopSubject as a9, type RepoHead as aA, type ReportedWindow as aB, type ResearchLogEntry as aC, type ResearchProgress as aD, type ResearchStep as aE, type ResearchStepOutcome as aF, type ResearchToolType as aG, type RevertCommand as aH, type RevertWatch as aI, type RunSettings as aJ, type RunnerId as aK, type RunnerSessionCost as aL, SEVERITY_LABEL as aM, type ScriptConsent as aN, type ScriptResult as aO, type SessionBilling as aP, type SetupFailure as aQ, type ShadowedSkill as aR, type SkillAppliesTo as aS, type SkillCatalog as aT, type SkillInfo as aU, type SkillLoad as aV, type SkillLoadNotice as aW, type SkillMetadata as aX, type SkillSource as aY, SkillsService as aZ, type StoredHandoff as a_, MAX_LOOP_ROUNDS as aa, type ModelUsage as ab, type PatchFlag as ac, type PatchView as ad, type PendingPlanTurn as ae, type PlanIsolation as af, type PlanState as ag, type PlanStatus as ah, type PlanUsage as ai, type PlannerCompaction as aj, type PlannerCompactionOutcome as ak, type PlannerContextPause as al, type PlannerResendState as am, type PlannerUsage as an, type PrepareIntent as ao, type PreparedTask as ap, type PreservedWork as aq, type PreviewRepo as ar, type PreviousWork as as, REPORT_MAX_CHARS as at, ROOT_NODE as au, type RefusedRemoval as av, type RepairEvidence as aw, type RepairWait as ax, type ReplyRun as ay, type RepoGroupLayout as az, type AwaitingReason as b, openingLines as b$, type SupervisorLevel as b0, type Task as b1, type TaskDiffRead as b2, type TaskDiffResult as b3, type TaskIsolation as b4, type TaskIsolationState as b5, type TaskLoop as b6, type TaskModelAssignment as b7, type TaskReportTo as b8, type TaskSkillNotice as b9, costText as bA, countedSessionCost as bB, createEmptyPlan as bC, createSkillsService as bD, createTask as bE, endAttemptUsage as bF, findingLines as bG, findingRefText as bH, flattenTasks as bI, flattenTasksWithParents as bJ, formatCost as bK, formatTokenCount as bL, handoffDigest as bM, handoffLines as bN, handoffPreviewLines as bO, handoffReferenceText as bP, handoffWakeLines as bQ, inLoop as bR, isAwaitingReason as bS, isMeasured as bT, isSupervisorLevel as bU, isUserMessage as bV, loopRemovalRefusal as bW, loopRoundOf as bX, migratePlanState as bY, modelCostTitle as bZ, namedHandoff as b_, type TaskSkillSnapshot as ba, type TaskSnapshot as bb, type TaskStatus as bc, type TaskType as bd, type TaskUsageSummary as be, type TreeSnapshot as bf, type UsageLine as bg, type UsageRecord as bh, type UsageTotals as bi, type Verdict as bj, type VerificationCheck as bk, type WrittenTaskRef as bl, actorAuthority as bm, addAttemptUsage as bn, addModelUsage as bo, addPlannerUsage as bp, addUsage as bq, addUsageTotals as br, artifactLines as bs, betweenRounds as bt, boundedHandoffLines as bu, byteSize as bv, checkHandoff as bw, checkOf as bx, contextMeterText as by, contextMeterTitle as bz, type ContextFill as c, outOfRounds as c0, parseFindingRef as c1, partedPromptUsage as c2, patchChangesText as c3, patchFlagText as c4, patchLines as c5, patchLinesText as c6, patchText as c7, patchView as c8, pausedOnLimit as c9, planUsage as ca, plannerContextFill as cb, readableTaskIds as cc, rejoinPlanTree as cd, removedAttempt as ce, resolveWrittenRef as cf, resumedSessionWindow as cg, savedPatchOf as ch, savedPatchView as ci, savedPatchViews as cj, severityLabel as ck, startAttemptUsage as cl, storedHandoff as cm, subagentCostTitle as cn, taskUsageSummary as co, tasksTotalText as cp, usageLine as cq, usageText as cr, waitsForApproval as cs, withPatch as ct, wordsFrom as cu, worstSeverity as cv, type ConversationMessage as d, type CostProvenance as e, DEFAULT_RUNNERS as f, DEFAULT_SUPERVISOR_RETRY_LIMIT as g, DIGEST_FINDINGS as h, type DiscoveredModel as i, type ExecutionCommandName as j, type ExecutionRecord as k, type GuardTrip as l, HANDOFF_PUSH_CHARS as m, type Handoff as n, type HandoffArtifact as o, type HandoffCheck as p, type HandoffCommit as q, type HandoffDigest as r, type HandoffEvidence as s, type HandoffFinding as t, type HandoffLogs as u, type HandoffPatch as v, type HandoffPins as w, type HandoffPreviewOptions as x, type HandoffTaskName as y, type IWorktreeIsolation as z };