@sublang/playbook 9.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 (64) hide show
  1. package/docs/cli.md +51 -8
  2. package/docs/embedding.md +38 -12
  3. package/package.json +7 -3
  4. package/reference/sdlc/captain.md +14 -10
  5. package/reference/sdlc/captain.playbook/captain.fsm.d.ts +33 -13
  6. package/reference/sdlc/captain.playbook/captain.fsm.js +80 -9
  7. package/reference/sdlc/captain.playbook/captain.fsm.ts +137 -18
  8. package/reference/sdlc/captain.playbook/captain.gears.md +10 -6
  9. package/reference/sdlc/captain.playbook/captain.playbook.d.ts +5 -1
  10. package/reference/sdlc/captain.playbook/captain.playbook.js +140 -10
  11. package/reference/sdlc/captain.playbook/captain.playbook.ts +188 -16
  12. package/reference/sdlc/code.md +0 -1
  13. package/reference/sdlc/code.playbook/bin/interactive-session.js +170 -17
  14. package/reference/sdlc/code.playbook/bin/launch-config.js +136 -4
  15. package/reference/sdlc/code.playbook/bin/playbook.js +81 -4
  16. package/reference/sdlc/code.playbook/bin/repository-effects.js +2930 -0
  17. package/reference/sdlc/code.playbook/bin/run.js +365 -63
  18. package/reference/sdlc/code.playbook/bin/session-store.js +2877 -209
  19. package/reference/sdlc/code.playbook/code.fsm.d.ts +7 -0
  20. package/reference/sdlc/code.playbook/code.fsm.js +74 -25
  21. package/reference/sdlc/code.playbook/code.fsm.ts +83 -29
  22. package/reference/sdlc/code.playbook/code.gears.md +0 -2
  23. package/reference/sdlc/code.playbook/code.playbook.d.ts +5 -2
  24. package/reference/sdlc/code.playbook/code.playbook.js +54 -2
  25. package/reference/sdlc/code.playbook/code.playbook.ts +75 -6
  26. package/reference/sdlc/code.playbook/code.registry.d.ts +10 -3
  27. package/reference/sdlc/code.playbook/code.registry.js +10 -3
  28. package/reference/sdlc/code.playbook/code.registry.ts +23 -5
  29. package/reference/sdlc/code.playbook/playbook-captain.d.ts +99 -7
  30. package/reference/sdlc/code.playbook/playbook-captain.js +1850 -72
  31. package/reference/sdlc/code.playbook/playbook-captain.ts +2759 -96
  32. package/reference/sdlc/decide.md +0 -1
  33. package/reference/sdlc/decide.playbook/decide.fsm.d.ts +7 -0
  34. package/reference/sdlc/decide.playbook/decide.fsm.js +80 -29
  35. package/reference/sdlc/decide.playbook/decide.fsm.ts +89 -31
  36. package/reference/sdlc/decide.playbook/decide.gears.md +0 -1
  37. package/reference/sdlc/decide.playbook/decide.playbook.d.ts +13 -5
  38. package/reference/sdlc/decide.playbook/decide.playbook.js +1712 -91
  39. package/reference/sdlc/decide.playbook/decide.playbook.ts +2677 -136
  40. package/reference/sdlc/decide.playbook/decide.registry.d.ts +7 -3
  41. package/reference/sdlc/decide.playbook/decide.registry.js +10 -3
  42. package/reference/sdlc/decide.playbook/decide.registry.ts +20 -5
  43. package/reference/sdlc/review.playbook/review.fsm.d.ts +7 -0
  44. package/reference/sdlc/review.playbook/review.fsm.js +133 -12
  45. package/reference/sdlc/review.playbook/review.fsm.ts +140 -12
  46. package/reference/sdlc/review.playbook/review.playbook.d.ts +5 -2
  47. package/reference/sdlc/review.playbook/review.playbook.js +65 -2
  48. package/reference/sdlc/review.playbook/review.playbook.ts +83 -6
  49. package/reference/sdlc/review.playbook/review.registry.d.ts +10 -3
  50. package/reference/sdlc/review.playbook/review.registry.js +10 -3
  51. package/reference/sdlc/review.playbook/review.registry.ts +23 -5
  52. package/slc/gears2fsm.md +6 -5
  53. package/slc/link.md +544 -41
  54. package/src/accepted-outcome.d.ts +18 -0
  55. package/src/accepted-outcome.js +94 -0
  56. package/src/accepted-outcome.ts +140 -0
  57. package/src/runtime.d.ts +164 -3
  58. package/src/runtime.ts +213 -2
  59. package/src/xstate-playbook-runtime.d.ts +149 -10
  60. package/src/xstate-playbook-runtime.js +2569 -270
  61. package/src/xstate-playbook-runtime.ts +4133 -490
  62. package/src/xstate-runtime.d.ts +59 -1
  63. package/src/xstate-runtime.js +866 -7
  64. package/src/xstate-runtime.ts +1397 -7
@@ -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;