@sublang/playbook 8.0.0 → 10.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +3 -3
  2. package/docs/cli.md +66 -23
  3. package/docs/configuration.md +13 -8
  4. package/docs/embedding.md +45 -14
  5. package/package.json +7 -3
  6. package/reference/sdlc/captain.md +14 -10
  7. package/reference/sdlc/captain.playbook/captain.fsm.d.ts +33 -13
  8. package/reference/sdlc/captain.playbook/captain.fsm.js +80 -9
  9. package/reference/sdlc/captain.playbook/captain.fsm.ts +137 -18
  10. package/reference/sdlc/captain.playbook/captain.gears.md +10 -6
  11. package/reference/sdlc/captain.playbook/captain.playbook.d.ts +5 -1
  12. package/reference/sdlc/captain.playbook/captain.playbook.js +151 -10
  13. package/reference/sdlc/captain.playbook/captain.playbook.ts +200 -14
  14. package/reference/sdlc/code.md +0 -1
  15. package/reference/sdlc/code.playbook/bin/interactive-session.js +170 -17
  16. package/reference/sdlc/code.playbook/bin/launch-config.js +136 -4
  17. package/reference/sdlc/code.playbook/bin/playbook.js +81 -4
  18. package/reference/sdlc/code.playbook/bin/repository-effects.js +2930 -0
  19. package/reference/sdlc/code.playbook/bin/run.js +365 -63
  20. package/reference/sdlc/code.playbook/bin/session-store.js +2877 -209
  21. package/reference/sdlc/code.playbook/code.fsm.d.ts +11 -1
  22. package/reference/sdlc/code.playbook/code.fsm.js +85 -29
  23. package/reference/sdlc/code.playbook/code.fsm.ts +95 -33
  24. package/reference/sdlc/code.playbook/code.gears.md +0 -2
  25. package/reference/sdlc/code.playbook/code.playbook.d.ts +5 -2
  26. package/reference/sdlc/code.playbook/code.playbook.js +67 -4
  27. package/reference/sdlc/code.playbook/code.playbook.ts +87 -8
  28. package/reference/sdlc/code.playbook/code.registry.d.ts +10 -3
  29. package/reference/sdlc/code.playbook/code.registry.js +10 -3
  30. package/reference/sdlc/code.playbook/code.registry.ts +23 -5
  31. package/reference/sdlc/code.playbook/playbook-captain.d.ts +99 -7
  32. package/reference/sdlc/code.playbook/playbook-captain.js +1894 -82
  33. package/reference/sdlc/code.playbook/playbook-captain.ts +2809 -109
  34. package/reference/sdlc/decide.md +0 -1
  35. package/reference/sdlc/decide.playbook/decide.fsm.d.ts +8 -1
  36. package/reference/sdlc/decide.playbook/decide.fsm.js +80 -29
  37. package/reference/sdlc/decide.playbook/decide.fsm.ts +89 -31
  38. package/reference/sdlc/decide.playbook/decide.gears.md +0 -1
  39. package/reference/sdlc/decide.playbook/decide.playbook.d.ts +15 -5
  40. package/reference/sdlc/decide.playbook/decide.playbook.js +1994 -191
  41. package/reference/sdlc/decide.playbook/decide.playbook.ts +3209 -404
  42. package/reference/sdlc/decide.playbook/decide.registry.d.ts +7 -3
  43. package/reference/sdlc/decide.playbook/decide.registry.js +10 -3
  44. package/reference/sdlc/decide.playbook/decide.registry.ts +20 -5
  45. package/reference/sdlc/review.playbook/review.fsm.d.ts +7 -0
  46. package/reference/sdlc/review.playbook/review.fsm.js +133 -12
  47. package/reference/sdlc/review.playbook/review.fsm.ts +140 -12
  48. package/reference/sdlc/review.playbook/review.playbook.d.ts +5 -2
  49. package/reference/sdlc/review.playbook/review.playbook.js +78 -4
  50. package/reference/sdlc/review.playbook/review.playbook.ts +95 -8
  51. package/reference/sdlc/review.playbook/review.registry.d.ts +10 -3
  52. package/reference/sdlc/review.playbook/review.registry.js +10 -3
  53. package/reference/sdlc/review.playbook/review.registry.ts +23 -5
  54. package/slc/gears2fsm.md +25 -7
  55. package/slc/link.md +727 -82
  56. package/src/accepted-outcome.d.ts +18 -0
  57. package/src/accepted-outcome.js +94 -0
  58. package/src/accepted-outcome.ts +140 -0
  59. package/src/runtime.d.ts +165 -3
  60. package/src/runtime.ts +214 -2
  61. package/src/xstate-playbook-runtime.d.ts +162 -13
  62. package/src/xstate-playbook-runtime.js +3344 -564
  63. package/src/xstate-playbook-runtime.ts +4873 -637
  64. package/src/xstate-runtime.d.ts +76 -8
  65. package/src/xstate-runtime.js +1001 -64
  66. package/src/xstate-runtime.ts +1640 -91
@@ -8,21 +8,23 @@
8
8
  // callerInput; pending Coder questions retain BOSS_REPLY
9
9
  // Adjudication: LLM judge per player state; coderOutput is carried verbatim
10
10
  // Nested call: literal review target through the shared bridge
11
- // Compat: artifact schema 2 / runtime ABI 1
11
+ // Compat: artifact schema 3 / runtime ABI 1
12
12
 
13
13
  import {
14
- RUNTIME_ABI,
15
14
  createXStatePlaybookRuntime,
16
15
  snapshotJsonValue,
17
16
  type PlaybookPlayerInput,
17
+ type XStatePlaybookRuntimeFactory,
18
+ type XStatePlaybookRuntimeConstruction,
18
19
  type XStatePromptIdentity,
19
- type XStatePlaybookRuntimeSpec,
20
+ type XStatePlaybookRuntimeSpecV3,
20
21
  } from '@sublang/playbook/xstate-runtime';
21
22
  import {
22
23
  codingMachine,
23
24
  type CodingInput,
24
25
  type PlayerInput,
25
26
  } from './code.fsm.js';
27
+ import type { PlaybookHostConstructionCapabilities } from './playbook-captain.js';
26
28
  import type {
27
29
  CaptainCallOptions,
28
30
  CaptainResult,
@@ -76,6 +78,9 @@ export type {
76
78
  };
77
79
 
78
80
  export type CodePlaybookOptions = CodingInput;
81
+ export type CodePlaybookHostCapabilities =
82
+ PlaybookHostConstructionCapabilities &
83
+ XStatePlaybookRuntimeConstruction<CodePlaybookOptions, object>['hostCapabilities'];
79
84
 
80
85
  const OPTION_KEYS = new Set(['runResults']);
81
86
  const PLACEHOLDER = /<(#|[A-Za-z_$][A-Za-z0-9_$-]*)>/g;
@@ -85,6 +90,9 @@ const CONTINUATION_PREAMBLE =
85
90
  const VERBATIM_PAYLOAD_FIELDS: ReadonlySet<string> = new Set([
86
91
  'coderOutput',
87
92
  ]);
93
+ const UNFINISHED_FINAL_STATE_IDS: ReadonlySet<string> = new Set([
94
+ 'reportedReviewFailure',
95
+ ]);
88
96
 
89
97
  function snapshotCodeOptions(value: unknown): CodePlaybookOptions {
90
98
  const captured = snapshotJsonValue(value, 'CODE runtime options');
@@ -164,13 +172,25 @@ function composePlayerPrompt(
164
172
  export const _internal = {
165
173
  composePlayerPrompt,
166
174
  VERBATIM_PAYLOAD_FIELDS,
175
+ UNFINISHED_FINAL_STATE_IDS,
167
176
  };
168
177
 
169
178
  const runtimeSpec = {
170
179
  label: 'CODE',
171
- compat: { artifactSchema: 2, runtimeAbi: RUNTIME_ABI },
180
+ // DR-022 / slc/link.md: the declaration carries the value current at link
181
+ // time — a literal, never the loading engine's RUNTIME_ABI self-report,
182
+ // which would follow whatever engine loads the module and make the
183
+ // factory's skew check compare that engine with itself.
184
+ compat: { artifactSchema: 3, runtimeAbi: 1 },
172
185
  snapshotOptions: snapshotCodeOptions,
173
- entryEvent: { type: 'START_CODE', textField: 'callerInput' },
186
+ entryEvent: {
187
+ type: 'START_CODE',
188
+ textField: 'callerInput',
189
+ // `startCoding` copies the entry text here, so the failure-state retry
190
+ // reads it back from the persisted machine snapshot and survives a
191
+ // continued session (DR-034).
192
+ contextField: 'callerInput',
193
+ },
174
194
  roleStates: {
175
195
  runFirstPhase: {
176
196
  role: 'coder',
@@ -182,16 +202,75 @@ const runtimeSpec = {
182
202
  label: 'Coder is implementing exactly one unfinished intent-record task.',
183
203
  },
184
204
  },
205
+ outcomeAuthority: {
206
+ governedPlayerStates: {
207
+ runFirstPhase: {
208
+ directCommit: {
209
+ fields: {
210
+ coderOutput: 'presentation',
211
+ latestCommit: 'effect',
212
+ },
213
+ repositoryDisposition: 'one-descendant-commit',
214
+ },
215
+ irCommit: {
216
+ fields: {
217
+ coderOutput: 'presentation',
218
+ latestCommit: 'effect',
219
+ irNumber: 'semantic',
220
+ irTask: 'semantic',
221
+ },
222
+ repositoryDisposition: 'one-descendant-commit',
223
+ },
224
+ needsBossReply: {
225
+ fields: { question: 'presentation' },
226
+ repositoryDisposition: 'deferred',
227
+ },
228
+ },
229
+ runIrTask: {
230
+ moreTasks: {
231
+ fields: {
232
+ coderOutput: 'presentation',
233
+ latestCommit: 'effect',
234
+ irTask: 'semantic',
235
+ },
236
+ repositoryDisposition: 'one-descendant-commit',
237
+ },
238
+ finalTask: {
239
+ fields: {
240
+ coderOutput: 'presentation',
241
+ latestCommit: 'effect',
242
+ },
243
+ repositoryDisposition: 'one-descendant-commit',
244
+ },
245
+ needsBossReply: {
246
+ fields: { question: 'presentation' },
247
+ repositoryDisposition: 'deferred',
248
+ },
249
+ },
250
+ },
251
+ },
185
252
  composePlayerPrompt: (
186
253
  input: PlaybookPlayerInput,
187
254
  promptIdentity: XStatePromptIdentity,
188
255
  ) => composePlayerPrompt(input as PlayerInput, promptIdentity),
189
256
  verbatimPayloadFields: VERBATIM_PAYLOAD_FIELDS,
190
257
  controlContextFields: ['phase'],
258
+ unfinishedFinalStateIds: UNFINISHED_FINAL_STATE_IDS,
191
259
  transitionEventFields: ['callerInput', 'answer', 'questionId'],
192
- } satisfies XStatePlaybookRuntimeSpec<CodePlaybookOptions>;
260
+ } satisfies XStatePlaybookRuntimeSpecV3<CodePlaybookOptions>;
193
261
 
194
- const createPlaybookRuntime: PlaybookRuntimeFactory<CodePlaybookOptions> =
195
- createXStatePlaybookRuntime(codingMachine, runtimeSpec);
262
+ const createPlaybookRuntime: XStatePlaybookRuntimeFactory<
263
+ XStatePlaybookRuntimeConstruction<
264
+ CodePlaybookOptions,
265
+ CodePlaybookHostCapabilities
266
+ >,
267
+ 3
268
+ > = createXStatePlaybookRuntime<
269
+ CodePlaybookOptions,
270
+ CodePlaybookHostCapabilities
271
+ >(
272
+ codingMachine,
273
+ runtimeSpec,
274
+ );
196
275
 
197
276
  export default createPlaybookRuntime;
@@ -1,4 +1,4 @@
1
- import { type PlaybookRuntime } from './code.playbook.js';
1
+ import { type CodePlaybookHostCapabilities, type PlaybookRuntime } from './code.playbook.js';
2
2
  export interface PlaybookSummaryPolicy {
3
3
  stateCountLabels: Readonly<Record<string, string>>;
4
4
  copyPasteGuardNames: readonly string[];
@@ -12,12 +12,19 @@ export interface CodePlaybookRegistryEntry {
12
12
  id: 'code';
13
13
  command: 'code';
14
14
  intent: string;
15
- artifactSchema: 2;
15
+ artifactSchema: 3;
16
+ runtimeProfile: {
17
+ readonly kind: 'shared-factory';
18
+ readonly compat: {
19
+ readonly artifactSchema: 3;
20
+ readonly runtimeAbi: number;
21
+ };
22
+ };
16
23
  requiredRoleIds: readonly ['coder'];
17
24
  concurrentRoleSets: readonly [];
18
25
  summaryPolicy: PlaybookSummaryPolicy;
19
26
  validateOptions(optionSlice: unknown): CodeOptions;
20
- createRuntime(options: CodeOptions): PlaybookRuntime;
27
+ createRuntime(options: CodeOptions, hostCapabilities: CodePlaybookHostCapabilities): PlaybookRuntime;
21
28
  }
22
29
  export declare const codeStateCountLabels: {};
23
30
  export declare const codeCopyPasteGuardNames: readonly ["directCommit", "irCommit", "moreTasks", "finalTask"];
@@ -47,13 +47,20 @@ export const codePlaybookRegistryEntry = {
47
47
  id: 'code',
48
48
  command: 'code',
49
49
  intent: 'implement a coding intent in reviewed, one-commit phases, using an intent record when needed',
50
- artifactSchema: 2,
50
+ artifactSchema: 3,
51
+ runtimeProfile: Object.freeze({
52
+ kind: 'shared-factory',
53
+ compat: createPlaybookRuntime.compat,
54
+ }),
51
55
  requiredRoleIds: ['coder'],
52
56
  concurrentRoleSets: [],
53
57
  summaryPolicy: codeSummaryPolicy,
54
58
  validateOptions: validateCodeOptions,
55
- createRuntime(options) {
56
- return createPlaybookRuntime(options);
59
+ createRuntime(options, hostCapabilities) {
60
+ return createPlaybookRuntime({
61
+ configuredOptions: options,
62
+ hostCapabilities,
63
+ });
57
64
  },
58
65
  };
59
66
  export default codePlaybookRegistryEntry;
@@ -2,6 +2,7 @@
2
2
  // SPDX-FileCopyrightText: 2026 SubLang International <https://sublang.ai>
3
3
 
4
4
  import createPlaybookRuntime, {
5
+ type CodePlaybookHostCapabilities,
5
6
  type PlaybookRuntime,
6
7
  } from './code.playbook.js';
7
8
 
@@ -20,12 +21,22 @@ export interface CodePlaybookRegistryEntry {
20
21
  id: 'code';
21
22
  command: 'code';
22
23
  intent: string;
23
- artifactSchema: 2;
24
+ artifactSchema: 3;
25
+ runtimeProfile: {
26
+ readonly kind: 'shared-factory';
27
+ readonly compat: {
28
+ readonly artifactSchema: 3;
29
+ readonly runtimeAbi: number;
30
+ };
31
+ };
24
32
  requiredRoleIds: readonly ['coder'];
25
33
  concurrentRoleSets: readonly [];
26
34
  summaryPolicy: PlaybookSummaryPolicy;
27
35
  validateOptions(optionSlice: unknown): CodeOptions;
28
- createRuntime(options: CodeOptions): PlaybookRuntime;
36
+ createRuntime(
37
+ options: CodeOptions,
38
+ hostCapabilities: CodePlaybookHostCapabilities,
39
+ ): PlaybookRuntime;
29
40
  }
30
41
 
31
42
  // REVIEW owns and labels its real review rounds. CODE's two suspended wrapper
@@ -91,13 +102,20 @@ export const codePlaybookRegistryEntry: CodePlaybookRegistryEntry = {
91
102
  command: 'code',
92
103
  intent:
93
104
  'implement a coding intent in reviewed, one-commit phases, using an intent record when needed',
94
- artifactSchema: 2,
105
+ artifactSchema: 3,
106
+ runtimeProfile: Object.freeze({
107
+ kind: 'shared-factory',
108
+ compat: createPlaybookRuntime.compat,
109
+ }),
95
110
  requiredRoleIds: ['coder'],
96
111
  concurrentRoleSets: [],
97
112
  summaryPolicy: codeSummaryPolicy,
98
113
  validateOptions: validateCodeOptions,
99
- createRuntime(options) {
100
- return createPlaybookRuntime(options);
114
+ createRuntime(options, hostCapabilities) {
115
+ return createPlaybookRuntime({
116
+ configuredOptions: options,
117
+ hostCapabilities,
118
+ });
101
119
  },
102
120
  };
103
121
 
@@ -1,6 +1,6 @@
1
1
  import { type Captain, type CaptainSession, type TuningSelection } from '@sublang/cligent/tmux-play';
2
2
  import type { Effort, PermissionPolicy } from '@sublang/cligent';
3
- import type { JsonValue, PlaybookRuntime, PlaybookRuntimeSnapshot } from '@sublang/playbook/runtime';
3
+ import type { JsonValue, PlaybookEffectLedger, PlaybookEffectLedgerCommandBatch, PlaybookRuntime, PlaybookRuntimeSnapshot } from '@sublang/playbook/runtime';
4
4
  import { type CaptainControllerPort } from '../captain.playbook/captain.playbook.js';
5
5
  import type { PlaybookSummaryPolicy } from './code.registry.js';
6
6
  interface SessionAgent {
@@ -19,11 +19,22 @@ interface PlayerLedgerEntry {
19
19
  type DeepReadonly<T> = T extends (...args: never[]) => unknown ? T : T extends readonly (infer Element)[] ? readonly DeepReadonly<Element>[] : T extends object ? {
20
20
  readonly [Key in keyof T]: DeepReadonly<T[Key]>;
21
21
  } : T;
22
+ export interface PlaybookCaptainUnresolvedEffect {
23
+ readonly classification: 'one-descendant-commit' | 'multiple-commits' | 'rewritten-or-non-descendant' | 'worktree-only-change' | 'concurrent-or-foreign-change' | 'observation-ambiguous' | 'incomplete';
24
+ readonly baselineHead: string;
25
+ readonly afterHead?: string;
26
+ readonly commitOid?: string;
27
+ }
28
+ interface PlaybookCaptainUnresolvedEffectSettlementInput {
29
+ readonly rootPlaybookId: string;
30
+ readonly unresolvedEffects: readonly PlaybookCaptainUnresolvedEffect[];
31
+ }
22
32
  type SnapshotAgentEnvelope = DeepReadonly<Omit<SessionAgent, 'model' | 'effort'>>;
23
33
  type PlayerLedgerSnapshotEntry = DeepReadonly<PlayerLedgerEntry>;
24
34
  export interface PlaybookCaptainDeps {
25
35
  loadModule?: (specifier: string) => Promise<unknown>;
26
36
  createSessionId?: () => string;
37
+ hostCapabilities?: Readonly<Record<string, PlaybookHostConstructionCapabilities>>;
27
38
  createCaptainRuntime?: (options: {
28
39
  readonly enabledPlaybooks: readonly {
29
40
  readonly id: string;
@@ -32,18 +43,67 @@ export interface PlaybookCaptainDeps {
32
43
  }[];
33
44
  readonly controller: CaptainControllerPort;
34
45
  }) => PlaybookRuntime;
46
+ unresolvedEffectSettlement?: {
47
+ begin(input: PlaybookCaptainUnresolvedEffectSettlementInput): Promise<void>;
48
+ complete(input: PlaybookCaptainUnresolvedEffectSettlementInput): Promise<void>;
49
+ };
50
+ }
51
+ /** Live, artifact-typed host facilities supplied outside configured options. */
52
+ export interface PlaybookHostConstructionCapabilities {
53
+ readonly authority: {
54
+ readonly playbookId: string;
55
+ readonly artifactSchema: 3;
56
+ readonly cwd: string;
57
+ readonly sessionId: string;
58
+ readonly leaseOwnerToken: string;
59
+ readonly canonicalWorktree: {
60
+ readonly worktree: string;
61
+ readonly gitDir: string;
62
+ };
63
+ readonly requiredRoleIds: readonly string[];
64
+ readonly concurrentRoleSets: readonly (readonly string[])[];
65
+ };
66
+ readonly repository: {
67
+ readonly identity: {
68
+ readonly worktree: string;
69
+ readonly gitDir: string;
70
+ };
71
+ readonly observe: (options?: unknown) => Promise<unknown>;
72
+ readonly acquire: (options?: unknown) => Promise<unknown>;
73
+ readonly runExclusive: (options: unknown) => Promise<unknown>;
74
+ readonly runCohort: (options: unknown) => Promise<unknown>;
75
+ readonly runDeferred: (options: unknown) => Promise<unknown>;
76
+ };
77
+ readonly effectLedger: {
78
+ readonly snapshot: () => PlaybookEffectLedger;
79
+ readonly writeAhead: (commands: PlaybookEffectLedgerCommandBatch) => Promise<PlaybookEffectLedger>;
80
+ };
35
81
  }
36
- export interface PlaybookCaptainRegistryEntry {
82
+ export type PlaybookCaptainRuntimeProfile = {
83
+ readonly kind: 'shared-factory';
84
+ readonly compat: {
85
+ readonly artifactSchema: 3;
86
+ readonly runtimeAbi: number;
87
+ };
88
+ } | {
89
+ readonly kind: 'bespoke';
90
+ readonly artifactSchema: 3;
91
+ };
92
+ interface PlaybookCaptainRegistryEntryBase {
37
93
  id: string;
38
94
  command: string;
39
95
  intent: string;
40
- artifactSchema: 2;
96
+ runtimeProfile: PlaybookCaptainRuntimeProfile;
41
97
  requiredRoleIds: readonly string[];
42
98
  concurrentRoleSets: readonly (readonly string[])[];
43
99
  summaryPolicy?: PlaybookSummaryPolicy;
44
100
  validateOptions(optionSlice: unknown): unknown;
45
- createRuntime(options: unknown): PlaybookRuntime;
46
101
  }
102
+ export interface PlaybookCaptainRegistryEntryV3 extends PlaybookCaptainRegistryEntryBase {
103
+ artifactSchema: 3;
104
+ createRuntime(configuredOptions: unknown, hostCapabilities: PlaybookHostConstructionCapabilities): PlaybookRuntime;
105
+ }
106
+ export type PlaybookCaptainRegistryEntry = PlaybookCaptainRegistryEntryV3;
47
107
  type PlaybookCaptainConversationSnapshot = {
48
108
  readonly kind: 'unopened';
49
109
  } | {
@@ -62,7 +122,7 @@ interface PlaybookCaptainJournalRecord {
62
122
  readonly kind: 'boss' | 'reply' | 'handoff' | 'action' | 'outcome';
63
123
  readonly payload: JsonValue;
64
124
  }
65
- interface PlaybookCaptainFrameSnapshot {
125
+ export interface PlaybookCaptainFrameSnapshot {
66
126
  readonly playbookId: string;
67
127
  readonly sessionId: string;
68
128
  readonly rootSessionId: string;
@@ -74,7 +134,8 @@ interface PlaybookCaptainFrameSnapshot {
74
134
  readonly runtime: DeepReadonly<PlaybookRuntimeSnapshot>;
75
135
  }
76
136
  interface PlaybookCaptainShellSnapshotFields {
77
- readonly schemaVersion: 3;
137
+ readonly schemaVersion: 4;
138
+ readonly effectLedger: DeepReadonly<PlaybookEffectLedger>;
78
139
  readonly captain: {
79
140
  readonly sessionId: string;
80
141
  readonly runtime: DeepReadonly<PlaybookRuntimeSnapshot>;
@@ -89,7 +150,7 @@ interface PlaybookCaptainShellSnapshotFields {
89
150
  readonly journal: number;
90
151
  };
91
152
  readonly journal: readonly PlaybookCaptainJournalRecord[];
92
- readonly lastAction?: 'respond' | 'start' | 'switch' | 'dismiss' | 'deliver' | 'runtime';
153
+ readonly lastAction?: 'respond' | 'start' | 'switch' | 'resume' | 'dismiss' | 'deliver' | 'runtime';
93
154
  readonly lastSettlementStatus?: 'ok' | 'rejected' | 'failed';
94
155
  }
95
156
  /**
@@ -105,6 +166,7 @@ type PlaybookCaptainShellSnapshotValue = PlaybookCaptainShellSnapshotFields & ({
105
166
  readonly mode: 'engaged.parked';
106
167
  /** Root-to-leaf engagement order. */
107
168
  readonly frames: readonly PlaybookCaptainFrameSnapshot[];
169
+ readonly retainedEffectReconciliation?: PlaybookCaptainRetainedEffectReconciliation;
108
170
  readonly pendingBossQuestions?: JsonValue;
109
171
  readonly lastError?: {
110
172
  readonly name: string;
@@ -112,11 +174,41 @@ type PlaybookCaptainShellSnapshotValue = PlaybookCaptainShellSnapshotFields & ({
112
174
  };
113
175
  });
114
176
  export type PlaybookCaptainShellSnapshot = DeepReadonly<PlaybookCaptainShellSnapshotValue>;
177
+ export interface PlaybookCaptainRetainedGeneration {
178
+ /** Repository-effect checkpoint reflected by the retained machine state. */
179
+ readonly effectLedger: DeepReadonly<PlaybookEffectLedger>;
180
+ readonly frames: readonly PlaybookCaptainFrameSnapshot[];
181
+ readonly retainedEffectReconciliation?: {
182
+ readonly sourceGenerationId: string;
183
+ };
184
+ /** Boss-facing description published for the retained root state, if any. */
185
+ readonly rootStateDescription?: string;
186
+ }
187
+ interface PlaybookCaptainRetainedEffectReconciliation {
188
+ readonly sourceGenerationId: string;
189
+ readonly checkpoint: DeepReadonly<PlaybookEffectLedger>;
190
+ }
191
+ export type PlaybookCaptainRetentionUpdate = {
192
+ readonly kind: 'retain';
193
+ readonly rootPlaybookId: string;
194
+ readonly generation: PlaybookCaptainRetainedGeneration;
195
+ } | {
196
+ readonly kind: 'clear';
197
+ readonly rootPlaybookId: string;
198
+ };
199
+ export interface PlaybookCaptainSettlement {
200
+ readonly snapshot: PlaybookCaptainShellSnapshot;
201
+ readonly retentionUpdates: readonly PlaybookCaptainRetentionUpdate[];
202
+ readonly unresolvedEffects: readonly PlaybookCaptainUnresolvedEffect[];
203
+ }
115
204
  /** tmux and headless front ends share this one durable Captain shell API. */
116
205
  export interface PlaybookCaptainShell extends Captain {
206
+ installRetainedGenerations(generations: Readonly<Record<string, PlaybookCaptainRetainedGeneration>>): Promise<void>;
117
207
  exportSnapshot(): PlaybookCaptainShellSnapshot | undefined;
208
+ exportSettlement(): PlaybookCaptainSettlement | undefined;
118
209
  restore(session: CaptainSession, snapshot: PlaybookCaptainShellSnapshot): Promise<void>;
119
210
  }
211
+ export declare function assertPlaybookCaptainUnresolvedEffects(value: unknown): readonly PlaybookCaptainUnresolvedEffect[];
120
212
  /** Validate, detach, and freeze one untrusted shell snapshot. */
121
213
  export declare function assertPlaybookCaptainShellSnapshot(value: unknown): PlaybookCaptainShellSnapshot;
122
214
  export declare function createPlaybookCaptainShell(options: unknown, deps?: PlaybookCaptainDeps): PlaybookCaptainShell;