@sublang/playbook 15.1.0 → 17.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 (102) hide show
  1. package/README.md +2 -0
  2. package/docs/cli.md +36 -18
  3. package/docs/configuration.md +7 -5
  4. package/docs/embedding.md +28 -7
  5. package/package.json +4 -4
  6. package/reference/sdlc/branch.playbook/branch.fsm.d.ts +63 -33
  7. package/reference/sdlc/branch.playbook/branch.fsm.js +190 -108
  8. package/reference/sdlc/branch.playbook/branch.fsm.ts +269 -147
  9. package/reference/sdlc/branch.playbook/branch.gears.md +7 -17
  10. package/reference/sdlc/branch.playbook/branch.playbook.d.ts +12 -16
  11. package/reference/sdlc/branch.playbook/branch.playbook.js +112 -101
  12. package/reference/sdlc/branch.playbook/branch.playbook.ts +128 -171
  13. package/reference/sdlc/branch.playbook/branch.registry.d.ts +3 -2
  14. package/reference/sdlc/branch.playbook/branch.registry.ts +6 -2
  15. package/reference/sdlc/captain.md +19 -10
  16. package/reference/sdlc/captain.playbook/captain.fsm.d.ts +6 -2
  17. package/reference/sdlc/captain.playbook/captain.fsm.js +19 -7
  18. package/reference/sdlc/captain.playbook/captain.fsm.ts +25 -10
  19. package/reference/sdlc/captain.playbook/captain.gears.md +16 -8
  20. package/reference/sdlc/captain.playbook/captain.playbook.d.ts +1 -1
  21. package/reference/sdlc/captain.playbook/captain.playbook.js +3 -2
  22. package/reference/sdlc/captain.playbook/captain.playbook.ts +4 -3
  23. package/reference/sdlc/code.playbook/bin/interactive-session.js +14 -1
  24. package/reference/sdlc/code.playbook/bin/portable-codec.js +3 -0
  25. package/reference/sdlc/code.playbook/bin/repository-effects.js +1 -0
  26. package/reference/sdlc/code.playbook/bin/run.js +128 -85
  27. package/reference/sdlc/code.playbook/bin/session-host.js +40 -8
  28. package/reference/sdlc/code.playbook/bin/session-store.js +162 -34
  29. package/reference/sdlc/code.playbook/code.fsm.d.ts +146 -93
  30. package/reference/sdlc/code.playbook/code.fsm.introspect.d.ts +8 -8
  31. package/reference/sdlc/code.playbook/code.fsm.introspect.ts +13 -13
  32. package/reference/sdlc/code.playbook/code.fsm.js +609 -649
  33. package/reference/sdlc/code.playbook/code.fsm.ts +890 -821
  34. package/reference/sdlc/code.playbook/code.gears.md +39 -29
  35. package/reference/sdlc/code.playbook/code.playbook.d.ts +13 -16
  36. package/reference/sdlc/code.playbook/code.playbook.js +166 -147
  37. package/reference/sdlc/code.playbook/code.playbook.ts +180 -229
  38. package/reference/sdlc/code.playbook/code.registry.d.ts +3 -2
  39. package/reference/sdlc/code.playbook/code.registry.ts +6 -2
  40. package/reference/sdlc/code.playbook/host-capabilities.d.ts +3 -0
  41. package/reference/sdlc/code.playbook/playbook-captain.d.ts +74 -2
  42. package/reference/sdlc/code.playbook/playbook-captain.js +1548 -468
  43. package/reference/sdlc/code.playbook/playbook-captain.ts +1993 -573
  44. package/reference/sdlc/code.playbook/session-host.d.ts +4 -1
  45. package/reference/sdlc/code.playbook/session-store.d.ts +17 -0
  46. package/reference/sdlc/code.playbook/session-store.js +1 -0
  47. package/reference/sdlc/decide.md +1 -0
  48. package/reference/sdlc/decide.playbook/decide.fsm.d.ts +273 -157
  49. package/reference/sdlc/decide.playbook/decide.fsm.js +765 -732
  50. package/reference/sdlc/decide.playbook/decide.fsm.ts +1167 -945
  51. package/reference/sdlc/decide.playbook/decide.gears.md +28 -21
  52. package/reference/sdlc/decide.playbook/decide.playbook.d.ts +11 -59
  53. package/reference/sdlc/decide.playbook/decide.playbook.js +155 -3696
  54. package/reference/sdlc/decide.playbook/decide.playbook.ts +186 -5244
  55. package/reference/sdlc/decide.playbook/decide.registry.d.ts +8 -4
  56. package/reference/sdlc/decide.playbook/decide.registry.js +2 -2
  57. package/reference/sdlc/decide.playbook/decide.registry.ts +13 -6
  58. package/reference/sdlc/dev.playbook/dev.fsm.d.ts +116 -134
  59. package/reference/sdlc/dev.playbook/dev.fsm.js +517 -575
  60. package/reference/sdlc/dev.playbook/dev.fsm.ts +667 -787
  61. package/reference/sdlc/dev.playbook/dev.gears.md +52 -54
  62. package/reference/sdlc/dev.playbook/dev.playbook.d.ts +13 -10
  63. package/reference/sdlc/dev.playbook/dev.playbook.js +128 -120
  64. package/reference/sdlc/dev.playbook/dev.playbook.ts +143 -193
  65. package/reference/sdlc/dev.playbook/dev.registry.d.ts +3 -2
  66. package/reference/sdlc/dev.playbook/dev.registry.ts +6 -2
  67. package/reference/sdlc/pr.playbook/pr.fsm.d.ts +95 -88
  68. package/reference/sdlc/pr.playbook/pr.fsm.js +461 -518
  69. package/reference/sdlc/pr.playbook/pr.fsm.ts +533 -663
  70. package/reference/sdlc/pr.playbook/pr.gears.md +47 -63
  71. package/reference/sdlc/pr.playbook/pr.playbook.d.ts +13 -23
  72. package/reference/sdlc/pr.playbook/pr.playbook.js +118 -112
  73. package/reference/sdlc/pr.playbook/pr.playbook.ts +136 -190
  74. package/reference/sdlc/pr.playbook/pr.registry.d.ts +3 -2
  75. package/reference/sdlc/pr.playbook/pr.registry.ts +4 -2
  76. package/reference/sdlc/review.md +3 -3
  77. package/reference/sdlc/review.playbook/review.fsm.d.ts +150 -116
  78. package/reference/sdlc/review.playbook/review.fsm.js +479 -550
  79. package/reference/sdlc/review.playbook/review.fsm.ts +717 -662
  80. package/reference/sdlc/review.playbook/review.gears.md +32 -29
  81. package/reference/sdlc/review.playbook/review.playbook.d.ts +12 -12
  82. package/reference/sdlc/review.playbook/review.playbook.js +180 -155
  83. package/reference/sdlc/review.playbook/review.playbook.ts +190 -230
  84. package/reference/sdlc/review.playbook/review.registry.d.ts +6 -5
  85. package/reference/sdlc/review.playbook/review.registry.js +3 -3
  86. package/reference/sdlc/review.playbook/review.registry.ts +9 -5
  87. package/slc/gears2fsm.md +77 -8
  88. package/slc/link.md +127 -60
  89. package/slc/materialize-link.mjs +51 -13
  90. package/slc/optimize.md +4 -1
  91. package/slc/prefix-prompts.mjs +29 -28
  92. package/slc/prefix.md +27 -24
  93. package/slc/slc.pin-inputs.json +11 -2
  94. package/slc/text2gears.md +71 -11
  95. package/src/runtime.d.ts +46 -2
  96. package/src/runtime.ts +42 -2
  97. package/src/xstate-playbook-runtime.d.ts +63 -23
  98. package/src/xstate-playbook-runtime.js +1637 -475
  99. package/src/xstate-playbook-runtime.ts +2105 -532
  100. package/src/xstate-runtime.d.ts +3 -4
  101. package/src/xstate-runtime.js +52 -0
  102. package/src/xstate-runtime.ts +59 -4
@@ -48,7 +48,7 @@ export interface OpenSessionHostOptions {
48
48
  readonly store?: SharedSessionStore;
49
49
  readonly sessionsDir?: string;
50
50
  readonly sessionId?: string;
51
- readonly mode?: 'new' | 'continue' | 'retry';
51
+ readonly mode?: 'new' | 'continue' | 'retry' | 'recover';
52
52
  readonly cwd?: string;
53
53
  readonly config?: SessionExecutionProjection;
54
54
  readonly plan?: any;
@@ -98,6 +98,9 @@ export interface SessionHostController {
98
98
  */
99
99
  submitShellAction(actionId: string): Promise<SessionRecovery>;
100
100
  retry(): Promise<SessionRecovery>;
101
+ /** Restore and report recorded uncertainty without running work; settled pauses require Boss input. Never discards work.
102
+ * After this live controller becomes uncertain, dispose and reopen with mode:'recover' first. */
103
+ recover(input?: string): Promise<SessionRecovery>;
101
104
  dispose(): Promise<void>;
102
105
  }
103
106
  export declare function openSessionHost(options: OpenSessionHostOptions): Promise<SessionHostController>;
@@ -113,6 +113,18 @@ export interface SessionStructuralProjection {
113
113
  readonly players: readonly Readonly<Record<string, any>>[];
114
114
  readonly catalog: Readonly<Record<string, any>>;
115
115
  }
116
+ export interface SessionStep {
117
+ readonly id: string;
118
+ readonly kind: 'player' | 'captain' | 'script' | 'preparation' | 'completion' | 'answer';
119
+ readonly stateId: string;
120
+ readonly runtimeSessionId: string;
121
+ readonly playbookId: string;
122
+ readonly result?: unknown;
123
+ }
124
+ export interface SessionProgressChange {
125
+ readonly snapshot?: SessionSnapshot | null;
126
+ readonly step?: SessionStep;
127
+ }
116
128
  export interface SessionRecovery {
117
129
  readonly schemaVersion: 6;
118
130
  readonly kind: 'captain-session';
@@ -135,6 +147,7 @@ export interface SessionRecovery {
135
147
  readonly markedAt: string;
136
148
  readonly attemptedExecutionProjection: SessionExecutionProjection;
137
149
  readonly abandonment?: Readonly<Record<string, any>>;
150
+ readonly progress?: { readonly snapshot: SessionSnapshot | null; readonly steps: readonly SessionStep[]; readonly positionStepId?: string | null };
138
151
  };
139
152
  }
140
153
  export interface SessionReplayCheckpoint {
@@ -215,6 +228,7 @@ export interface PlaybookSessionLifecycle extends PlaybookSessionLease {
215
228
  abandonFreshSettled(options: { expected: SessionRecovery }): Promise<boolean>;
216
229
  beginTurn(options: { input: string; attemptId: string; attemptedExecutionProjection: SessionExecutionProjection }): Promise<SessionRecovery>;
217
230
  beginRetry(options: { expectedAttemptId: string; nextAttemptId: string }): Promise<SessionRecovery>;
231
+ recordProgress(change: SessionProgressChange): Promise<void>;
218
232
  settle(options: { attemptId: string; snapshot: SessionSnapshot; unresolvedEffects: readonly SessionUnresolvedEffect[]; retentionUpdates?: readonly SessionRetentionUpdate[] }): Promise<SessionRecovery>;
219
233
  discard(options: { attemptId: string }): Promise<SessionRecovery | undefined>;
220
234
  beginUnresolvedEffectAbandonment(options: any): Promise<any>;
@@ -255,3 +269,6 @@ export declare function validateCaptainSessionExecutionProjection(value: unknown
255
269
  export declare function validateCaptainSessionStructuralProjection(value: unknown): SessionStructuralProjection;
256
270
  export declare function assertCaptainSessionExecutionCompatible(structural: SessionStructuralProjection, execution: SessionExecutionProjection): SessionExecutionProjection;
257
271
  export declare function attachSessionHints(snapshot: SessionSnapshot, hints: SessionHints): SessionSnapshot;
272
+
273
+ /** Whether discarding an uncertain turn restores its untouched baseline. */
274
+ export declare function isUncertainTurnDiscardable(record: SessionRecovery): boolean;
@@ -117,6 +117,7 @@ function projectStatus(status) {
117
117
 
118
118
  export {
119
119
  createCaptainSessionStore as createSessionStore,
120
+ isUncertainTurnDiscardable,
120
121
  projectCaptainSessionStructure,
121
122
  validateCaptainSessionExecutionProjection,
122
123
  validateCaptainSessionStructuralProjection,
@@ -56,6 +56,7 @@ After Coder commits, Captain shall call playbook `review` with the following inp
56
56
 
57
57
  > Original intent: \<caller-topic\>
58
58
  > Review scope: the `decide`-owned commit \<decide-commit\> and its resulting repository state.
59
+ > Coder's independent proposal: \<coder-proposal\>
59
60
  > Coder output: \<coder-output\>
60
61
 
61
62
  `decide` is complete only when `review` returns a result that applies to the supplied review scope, gives the exact evaluated repository revision, and affirmatively establishes that no unsettled findings remain.
@@ -1,138 +1,217 @@
1
+ import type { PlaybookCallResult } from '@sublang/playbook/runtime';
1
2
  export type JsonValue = null | boolean | number | string | readonly JsonValue[] | {
2
3
  readonly [key: string]: JsonValue;
3
4
  };
4
- type Role = 'coder' | 'reviewer';
5
- export declare const concurrentRoleSets: readonly [readonly ["coder", "reviewer"]];
6
- type JumpableStateId = 'independentProposals';
7
- type ResumableStateId = 'askCoderProposal' | 'askReviewerProposal' | 'commitCoderProposal';
5
+ export interface CompactError {
6
+ readonly name: string;
7
+ readonly message: string;
8
+ }
9
+ export interface ErrorRecord {
10
+ readonly name: string;
11
+ readonly message: string;
12
+ readonly stack?: string;
13
+ }
14
+ /** Canonical lowercase local ids of the source roles Coder and Reviewer. */
15
+ export type DecideRoleId = 'coder' | 'reviewer';
16
+ export type DecideSourceItem = 'DECIDE-1' | 'DECIDE-2' | 'DECIDE-3' | 'DECIDE-4';
17
+ /** Delegated-player working leaves; each is its own Boss-reply resume target. */
18
+ export type ResumableStateId = 'askCoderProposal' | 'askReviewerProposal' | 'synthesizeCommit';
19
+ /**
20
+ * Root `BOSS_INTERRUPT` targets: the parallel proposal pair as one jumpable
21
+ * unit (DECIDE-1, DECIDE-2), and the synthesis leaf (DECIDE-3). Branch working
22
+ * leaves and waits are never interrupt targets.
23
+ */
24
+ export type JumpableStateId = 'independentProposals' | 'synthesizeCommit';
25
+ /**
26
+ * One role-id array per parallel group, in first-item source order; the inner
27
+ * array follows the `independent-proposals` item order (DECIDE-1, DECIDE-2).
28
+ */
29
+ export declare const concurrentRoleSets: readonly (readonly DecideRoleId[])[];
30
+ /** The literal nested-call target of DECIDE-4. */
31
+ declare const REVIEW_PLAYBOOK_ID: "review";
8
32
  export interface PendingBossQuestion {
9
- questionId: ResumableStateId;
10
- resumeStateId: ResumableStateId;
11
- sourceItem: string;
12
- asker: {
13
- kind: 'role';
14
- roleId: Role;
33
+ readonly questionId: ResumableStateId;
34
+ readonly resumeStateId: ResumableStateId;
35
+ readonly sourceItem: 'DECIDE-1' | 'DECIDE-2' | 'DECIDE-3';
36
+ readonly asker: {
37
+ readonly kind: 'role';
38
+ readonly roleId: DecideRoleId;
15
39
  };
16
- question: string;
40
+ readonly question: string;
17
41
  }
18
- type PendingBossQuestions = Partial<Record<ResumableStateId, PendingBossQuestion>>;
19
- type BossReplies = Partial<Record<ResumableStateId, string>>;
20
- type PendingBossQuestionParams = Omit<PendingBossQuestion, 'questionId'>;
21
- export interface ReviewSuccessOutput {
22
- evaluatedRevision: string;
23
- noUnsettledFindings: true;
42
+ export type PendingBossQuestions = Partial<Record<ResumableStateId, PendingBossQuestion>>;
43
+ export type BossReplies = Partial<Record<ResumableStateId, string>>;
44
+ declare const CODER_PROPOSAL_RESULT: {
45
+ readonly proposed: "Coder affirmatively provided a complete design proposal; a progress report, status update, or promise of a later proposal supports no proposal outcome. Output shall include `coderProposal: <verbatim final text>`.";
46
+ readonly needsBossReply: "The acting agent's prose surfaces a clarifying question for Boss that the agent cannot answer alone. Output shall include `question: <verbatim question text from the acting agent's prose>`.";
47
+ };
48
+ declare const REVIEWER_PROPOSAL_RESULT: {
49
+ readonly proposed: "Reviewer affirmatively provided a complete design proposal; a progress report, status update, or promise of a later proposal supports no proposal outcome. Output shall include `reviewerProposal: <verbatim final text>`.";
50
+ readonly needsBossReply: "The acting agent's prose surfaces a clarifying question for Boss that the agent cannot answer alone. Output shall include `question: <verbatim question text from the acting agent's prose>`.";
51
+ };
52
+ declare const SYNTHESIZE_COMMIT_RESULT: {
53
+ readonly committed: "Coder synthesized the proposals into the necessary DRs and/or spec items and committed the result as one new commit. Output shall include `coderOutput: <verbatim final text>` and `latestCommit: <commit identity>`.";
54
+ readonly needsBossReply: "The acting agent's prose surfaces a clarifying question for Boss that the agent cannot answer alone. Output shall include `question: <verbatim question text from the acting agent's prose>`.";
55
+ };
56
+ interface PlayerInputBase {
57
+ readonly pendingBossQuestion?: PendingBossQuestion;
58
+ readonly bossReply?: string;
24
59
  }
25
- export interface DecideSuccessOutput {
26
- decideCommit: string;
27
- evaluatedRevision: string;
28
- noUnsettledFindings: true;
60
+ /** DECIDE-1: relays `<caller-topic>` as `callerTopic`. */
61
+ export interface CoderProposalInput extends PlayerInputBase {
62
+ readonly stateId: 'askCoderProposal';
63
+ readonly role: 'coder';
64
+ readonly sourceItem: 'DECIDE-1';
65
+ readonly prompt: string;
66
+ readonly result: typeof CODER_PROPOSAL_RESULT;
67
+ /** `<caller-topic>`: the caller's complete topic. */
68
+ readonly callerTopic: string;
29
69
  }
30
- export interface DecideFailureOutput {
31
- lastDecideCommit: string;
32
- noUnsettledFindings: false;
33
- reviewStatus: 'aborted' | 'error';
34
- error?: {
35
- name: string;
36
- message: string;
37
- };
70
+ /** DECIDE-2: relays `<caller-topic>` as `callerTopic`. */
71
+ export interface ReviewerProposalInput extends PlayerInputBase {
72
+ readonly stateId: 'askReviewerProposal';
73
+ readonly role: 'reviewer';
74
+ readonly sourceItem: 'DECIDE-2';
75
+ readonly prompt: string;
76
+ readonly result: typeof REVIEWER_PROPOSAL_RESULT;
77
+ /** `<caller-topic>`: the caller's complete topic. */
78
+ readonly callerTopic: string;
38
79
  }
39
- export type DecideOutput = DecideSuccessOutput | DecideFailureOutput;
40
- interface ChildFailure {
41
- status: 'aborted' | 'error';
42
- playbookId: 'review';
43
- error?: {
44
- name: string;
45
- message: string;
46
- };
80
+ /**
81
+ * DECIDE-3: relays `<caller-topic>` as `callerTopic` and
82
+ * `<reviewer-proposal>` as `reviewerProposal`.
83
+ */
84
+ export interface SynthesizeCommitInput extends PlayerInputBase {
85
+ readonly stateId: 'synthesizeCommit';
86
+ readonly role: 'coder';
87
+ readonly sourceItem: 'DECIDE-3';
88
+ readonly prompt: string;
89
+ readonly result: typeof SYNTHESIZE_COMMIT_RESULT;
90
+ /** `<caller-topic>`: the caller's complete topic. */
91
+ readonly callerTopic: string;
92
+ /** `<reviewer-proposal>`: Reviewer's complete independent proposal. */
93
+ readonly reviewerProposal: string;
47
94
  }
48
- export interface DecideContext {
49
- callerTopic?: string;
50
- coderProposal?: string;
51
- reviewerProposal?: string;
52
- latestCommit?: string;
53
- coderOutput?: string;
54
- reviewResult?: ReviewSuccessOutput;
55
- reviewFailure?: ChildFailure;
56
- lastResult?: PlayerOutput;
57
- lastError?: unknown;
58
- pendingBossQuestions?: PendingBossQuestions;
59
- bossReplies?: BossReplies;
60
- stagedCoderResult?: PlayerOutput;
61
- stagedReviewerResult?: PlayerOutput;
95
+ export type PlayerInput = CoderProposalInput | ReviewerProposalInput | SynthesizeCommitInput;
96
+ export interface NeedsBossReplyOutput {
97
+ readonly guard: 'needsBossReply';
98
+ readonly question: string;
62
99
  }
63
- export type DecideEvent = {
64
- type: 'START_DECIDE';
65
- callerTopic: string;
66
- } | {
67
- type: 'BOSS_INTERRUPT';
68
- targetId: JumpableStateId;
69
- bossIntent: string;
100
+ export type CoderProposalOutput = {
101
+ readonly guard: 'proposed';
102
+ readonly coderProposal: string;
103
+ } | NeedsBossReplyOutput;
104
+ export type ReviewerProposalOutput = {
105
+ readonly guard: 'proposed';
106
+ readonly reviewerProposal: string;
107
+ } | NeedsBossReplyOutput;
108
+ export type SynthesizeCommitOutput = {
109
+ readonly guard: 'committed';
110
+ readonly coderOutput: string;
111
+ /** Effect-owned: the runtime fills it from the repository receipt. */
112
+ readonly latestCommit: string;
113
+ } | NeedsBossReplyOutput;
114
+ export type PlayerOutput = CoderProposalOutput | ReviewerProposalOutput | SynthesizeCommitOutput;
115
+ /** DECIDE-4: literal call of the builtin `review` playbook. */
116
+ export interface PlaybookInput {
117
+ readonly stateId: 'reviewCommit';
118
+ readonly sourceItem?: 'DECIDE-4';
119
+ readonly playbookId: typeof REVIEW_PLAYBOOK_ID;
120
+ readonly text: string;
121
+ }
122
+ /** A successful call yields the child's own JSON-safe machine output. */
123
+ export type PlaybookOutput = JsonValue | undefined;
124
+ /** Public output interface of the packaged builtin `review`. */
125
+ export interface ReviewOutput {
126
+ readonly noUnsettledFindings: true;
127
+ readonly evaluatedRevision: string;
128
+ }
129
+ /** Sanitized completed-result evidence of the `review` call that ended DECIDE. */
130
+ export type CompletedReviewResult = {
131
+ readonly playbookId: typeof REVIEW_PLAYBOOK_ID;
132
+ readonly status: 'ok';
133
+ readonly output?: JsonValue;
70
134
  } | {
71
- type: 'BOSS_REPLY';
72
- questionId?: ResumableStateId;
73
- answer: string;
135
+ readonly playbookId: typeof REVIEW_PLAYBOOK_ID;
136
+ readonly status: 'aborted' | 'error';
137
+ readonly error: CompactError;
74
138
  };
139
+ /** The machine reads no input: the caller's topic arrives on `START_DECIDE`. */
75
140
  export type DecideInput = Readonly<Record<string, never>>;
76
- export interface PlayerInput {
77
- stateId: ResumableStateId;
78
- sourceItem: string;
79
- prompt: string;
80
- result: Record<string, string>;
81
- role: Role;
82
- callerTopic?: string;
83
- reviewerProposal?: string;
84
- pendingBossQuestion?: PendingBossQuestion;
85
- bossReply?: string;
86
- }
87
- type AdditionalPlayerFields = {
88
- coderProposal?: string;
89
- reviewerProposal?: string;
90
- coderOutput?: string;
91
- latestCommit?: string;
92
- question?: string;
93
- readonly [key: string]: unknown;
94
- };
95
- export type PlayerOutput = ({
96
- guard: 'proposed';
97
- coderProposal: string;
98
- } & AdditionalPlayerFields) | ({
99
- guard: 'proposed';
100
- reviewerProposal: string;
101
- } & AdditionalPlayerFields) | ({
102
- guard: 'committed';
103
- coderOutput: string;
104
- latestCommit: string;
105
- } & AdditionalPlayerFields) | ({
106
- guard: 'needsBossReply';
107
- question: string;
108
- } & AdditionalPlayerFields);
109
- export interface PlaybookInput {
110
- stateId: 'reviewCommit';
111
- sourceItem: 'DECIDE-4';
112
- playbookId: 'review';
113
- text: string;
141
+ export type ReviewStatus = 'aborted' | 'error';
142
+ /**
143
+ * Typed run context. A text field holds `''` until its producer runs; every
144
+ * transition that enters a consumer guards the fields it reads as non-empty.
145
+ */
146
+ export interface DecideContext {
147
+ /** `<caller-topic>`: set by `START_DECIDE` or a restarting interrupt. */
148
+ readonly callerTopic: string;
149
+ /** Branch-staged proposals; the parallel join promotes them atomically. */
150
+ readonly stagedCoderProposal: string;
151
+ readonly stagedReviewerProposal: string;
152
+ /** `<coder-proposal>`: Coder's promoted independent proposal. */
153
+ readonly coderProposal: string;
154
+ /** `<reviewer-proposal>`: Reviewer's promoted independent proposal. */
155
+ readonly reviewerProposal: string;
156
+ /** `<coder-output>`: Coder's verbatim final synthesis text. */
157
+ readonly coderOutput: string;
158
+ /** `<decide-commit>`: DECIDE-3's accepted, receipt-owned `latestCommit`. */
159
+ readonly decideCommit: string;
160
+ /** Revision evaluated by the passing `review`. */
161
+ readonly evaluatedRevision: string;
162
+ /** Reported status when `review` did not pass the commit. */
163
+ readonly reviewStatus: ReviewStatus | null;
164
+ /** Compact failure DECIDE reports when `review` did not pass the commit. */
165
+ readonly reviewError: CompactError | null;
166
+ /** Sanitized evidence of the `review` result that ended DECIDE. */
167
+ readonly reviewEvidence: CompletedReviewResult | null;
168
+ readonly lastError: ErrorRecord | null;
169
+ readonly pendingBossQuestions: PendingBossQuestions;
170
+ readonly bossReplies: BossReplies;
114
171
  }
115
- export declare const decideMachine: import("xstate").StateMachine<DecideContext, {
116
- type: "START_DECIDE";
117
- callerTopic: string;
172
+ export type DecideEvent = {
173
+ readonly type: 'START_DECIDE';
174
+ readonly callerTopic: string;
118
175
  } | {
119
- type: "BOSS_INTERRUPT";
120
- targetId: JumpableStateId;
121
- bossIntent: string;
176
+ readonly type: 'BOSS_INTERRUPT';
177
+ readonly targetId: 'independentProposals';
178
+ /** The new topic both proposal players receive. */
179
+ readonly callerTopic: string;
122
180
  } | {
123
- type: "BOSS_REPLY";
124
- questionId?: ResumableStateId;
125
- answer: string;
126
- }, {
127
- [x: string]: import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<JsonValue | undefined, PlaybookInput, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<PlayerOutput, PlayerInput, import("xstate").EventObject>> | undefined;
128
- }, {
129
- src: "playbook";
130
- logic: import("xstate").PromiseActorLogic<JsonValue | undefined, PlaybookInput, import("xstate").EventObject>;
131
- id: string | undefined;
181
+ readonly type: 'BOSS_INTERRUPT';
182
+ readonly targetId: 'synthesizeCommit';
132
183
  } | {
184
+ readonly type: 'BOSS_REPLY';
185
+ readonly questionId: string;
186
+ readonly answer: string;
187
+ };
188
+ /** Exactly the catalog's public `decide` output interface. */
189
+ export type DecideOutput = {
190
+ readonly decideCommit: string;
191
+ readonly evaluatedRevision: string;
192
+ readonly noUnsettledFindings: true;
193
+ } | {
194
+ readonly lastDecideCommit: string;
195
+ readonly noUnsettledFindings: false;
196
+ readonly reviewStatus: ReviewStatus;
197
+ readonly error?: CompactError;
198
+ };
199
+ /**
200
+ * Recognizes an authored rejected child result: a validated public result
201
+ * whose status is `aborted` or `error`, or `ok` at the child's own authored
202
+ * failure terminal. Anything else is a control-plane error.
203
+ */
204
+ export declare function authoredChildResult(error: unknown, expectedPlaybookId: string): PlaybookCallResult | undefined;
205
+ export declare const decideMachine: import("xstate").StateMachine<DecideContext, import("xstate").AnyEventObject, {
206
+ [x: string]: import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<PlayerOutput, PlayerInput, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<PlaybookOutput, PlaybookInput, import("xstate").EventObject>> | undefined;
207
+ }, {
133
208
  src: "player";
134
209
  logic: import("xstate").PromiseActorLogic<PlayerOutput, PlayerInput, import("xstate").EventObject>;
135
210
  id: string | undefined;
211
+ } | {
212
+ src: "playbook";
213
+ logic: import("xstate").PromiseActorLogic<PlaybookOutput, PlaybookInput, import("xstate").EventObject>;
214
+ id: string | undefined;
136
215
  }, {
137
216
  type: "playbook.acceptedOutcome";
138
217
  params: {
@@ -145,12 +224,33 @@ export declare const decideMachine: import("xstate").StateMachine<DecideContext,
145
224
  params: import("xstate").NonReducibleUnknown;
146
225
  } | {
147
226
  type: "rememberBossReply";
227
+ params: {
228
+ readonly stateId: ResumableStateId;
229
+ };
230
+ } | {
231
+ type: "rememberMalformedPlayerOutput";
232
+ params: {
233
+ readonly sourceItem: DecideSourceItem;
234
+ };
235
+ } | {
236
+ type: "rememberAuthoredReviewFailure";
148
237
  params: import("xstate").NonReducibleUnknown;
149
238
  } | {
150
- type: "copyInterruptedTopic";
239
+ type: "setPendingBossQuestion";
240
+ params: {
241
+ readonly stateId: ResumableStateId;
242
+ };
243
+ } | {
244
+ type: "restartFromInterrupt";
151
245
  params: import("xstate").NonReducibleUnknown;
152
246
  } | {
153
- type: "copyStartTopic";
247
+ type: "rememberEmptyBossReply";
248
+ params: import("xstate").NonReducibleUnknown;
249
+ } | {
250
+ type: "rememberUnknownBossReply";
251
+ params: import("xstate").NonReducibleUnknown;
252
+ } | {
253
+ type: "startDecide";
154
254
  params: import("xstate").NonReducibleUnknown;
155
255
  } | {
156
256
  type: "stageCoderProposal";
@@ -165,61 +265,71 @@ export declare const decideMachine: import("xstate").StateMachine<DecideContext,
165
265
  type: "rememberCommit";
166
266
  params: import("xstate").NonReducibleUnknown;
167
267
  } | {
168
- type: "rememberReviewSuccess";
169
- params: import("xstate").NonReducibleUnknown;
170
- } | {
171
- type: "rememberReviewFailure";
268
+ type: "rememberReviewApproval";
172
269
  params: import("xstate").NonReducibleUnknown;
173
270
  } | {
174
- type: "rememberReviewProtocolFailure";
271
+ type: "rememberUnestablishedReview";
175
272
  params: import("xstate").NonReducibleUnknown;
273
+ }, {
274
+ type: "needsBossReply";
275
+ params: unknown;
176
276
  } | {
177
- type: "rememberMalformedActorOutput";
178
- params: import("xstate").NonReducibleUnknown;
277
+ type: "authoredReviewFailure";
278
+ params: unknown;
179
279
  } | {
180
- type: "rememberMalformedBossReply";
181
- params: import("xstate").NonReducibleUnknown;
280
+ type: "committed";
281
+ params: unknown;
182
282
  } | {
183
- type: "setPendingBossQuestion";
184
- params: PendingBossQuestionParams;
283
+ type: "interruptTargets";
284
+ params: {
285
+ readonly targetId: JumpableStateId;
286
+ };
185
287
  } | {
186
- type: "clearBranchBossReplyContext";
288
+ type: "bossReplyIsEmpty";
187
289
  params: {
188
- stateId: ResumableStateId;
290
+ readonly stateId: ResumableStateId;
189
291
  };
190
292
  } | {
191
- type: "clearProposalRoundContext";
192
- params: import("xstate").NonReducibleUnknown;
293
+ type: "bossReplyResumes";
294
+ params: {
295
+ readonly stateId: ResumableStateId;
296
+ };
193
297
  } | {
194
- type: "clearBossReplyContext";
195
- params: import("xstate").NonReducibleUnknown;
196
- }, {
197
- type: "authoredReviewFailure";
298
+ type: "bossReplyNamesNoPendingQuestion";
198
299
  params: unknown;
199
300
  } | {
200
- type: "committed";
301
+ type: "validStartTopic";
201
302
  params: unknown;
202
303
  } | {
203
- type: "coderProposed";
304
+ type: "coderProposedJoining";
204
305
  params: unknown;
205
306
  } | {
206
- type: "reviewerProposed";
307
+ type: "coderProposed";
207
308
  params: unknown;
208
309
  } | {
209
- type: "needsBossReplyWithQuestion";
310
+ type: "reviewerProposedJoining";
210
311
  params: unknown;
211
312
  } | {
212
- type: "needsBossReplyWithoutQuestion";
313
+ type: "reviewerProposed";
213
314
  params: unknown;
214
315
  } | {
215
- type: "validReviewSuccess";
316
+ type: "reviewApproved";
216
317
  params: unknown;
217
- }, never, "done" | "failed" | "ready" | "awaitBossReply" | "reportedReviewFailure" | "commitCoderProposal" | "reviewCommit" | {
318
+ }, never, "done" | "failed" | "ready" | "awaitBossReply" | "synthesizeCommit" | "reviewCommit" | "reportedReviewFailure" | {
218
319
  independentProposals: {
219
- coder: "complete" | "working" | "waiting";
220
- reviewer: "complete" | "working" | "waiting";
320
+ coderProposalRegion: "askCoderProposal" | "awaitCoderProposalReply" | "coderProposalStaged";
321
+ reviewerProposalRegion: "askReviewerProposal" | "awaitReviewerProposalReply" | "reviewerProposalStaged";
221
322
  };
222
- }, string, Readonly<Record<string, never>>, DecideSuccessOutput | DecideFailureOutput, import("xstate").EventObject, import("xstate").MetaObject, {
323
+ }, string, Readonly<Record<string, never>>, {
324
+ readonly decideCommit: string;
325
+ readonly evaluatedRevision: string;
326
+ readonly noUnsettledFindings: true;
327
+ } | {
328
+ readonly lastDecideCommit: string;
329
+ readonly noUnsettledFindings: false;
330
+ readonly reviewStatus: ReviewStatus;
331
+ readonly error?: CompactError;
332
+ }, import("xstate").EventObject, import("xstate").MetaObject, {
223
333
  id: "decide";
224
334
  states: {
225
335
  readonly ready: {
@@ -228,32 +338,38 @@ export declare const decideMachine: import("xstate").StateMachine<DecideContext,
228
338
  readonly independentProposals: {
229
339
  id: "independentProposals";
230
340
  states: {
231
- readonly coder: {
341
+ readonly coderProposalRegion: {
342
+ id: "coderProposalRegion";
232
343
  states: {
233
- readonly working: {
344
+ readonly askCoderProposal: {
234
345
  id: "askCoderProposal";
235
346
  };
236
- readonly waiting: {
237
- id: "waitCoderProposalReply";
347
+ readonly awaitCoderProposalReply: {
348
+ id: "awaitCoderProposalReply";
349
+ };
350
+ readonly coderProposalStaged: {
351
+ id: "coderProposalStaged";
238
352
  };
239
- readonly complete: {};
240
353
  };
241
354
  };
242
- readonly reviewer: {
355
+ readonly reviewerProposalRegion: {
356
+ id: "reviewerProposalRegion";
243
357
  states: {
244
- readonly working: {
358
+ readonly askReviewerProposal: {
245
359
  id: "askReviewerProposal";
246
360
  };
247
- readonly waiting: {
248
- id: "waitReviewerProposalReply";
361
+ readonly awaitReviewerProposalReply: {
362
+ id: "awaitReviewerProposalReply";
363
+ };
364
+ readonly reviewerProposalStaged: {
365
+ id: "reviewerProposalStaged";
249
366
  };
250
- readonly complete: {};
251
367
  };
252
368
  };
253
369
  };
254
370
  };
255
- readonly commitCoderProposal: {
256
- id: "commitCoderProposal";
371
+ readonly synthesizeCommit: {
372
+ id: "synthesizeCommit";
257
373
  };
258
374
  readonly awaitBossReply: {
259
375
  id: "awaitBossReply";