@sublang/playbook 4.0.0 → 6.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.
- package/README.md +69 -122
- package/docs/assets/playbook-venn.svg +13 -0
- package/docs/cli.md +43 -26
- package/docs/configuration.md +63 -18
- package/docs/embedding.md +24 -16
- package/package.json +43 -22
- package/reference/sdlc/captain.md +70 -83
- package/reference/sdlc/captain.playbook/captain.fsm.d.ts +127 -142
- package/reference/sdlc/captain.playbook/captain.fsm.js +349 -470
- package/reference/sdlc/captain.playbook/captain.fsm.ts +535 -598
- package/reference/sdlc/captain.playbook/captain.gears.md +37 -41
- package/reference/sdlc/captain.playbook/captain.playbook.d.ts +90 -15
- package/reference/sdlc/captain.playbook/captain.playbook.js +466 -976
- package/reference/sdlc/captain.playbook/captain.playbook.ts +698 -1001
- package/reference/sdlc/code.md +55 -97
- package/reference/sdlc/code.playbook/code.fsm.d.ts +229 -94
- package/reference/sdlc/code.playbook/code.fsm.introspect.d.ts +26 -44
- package/reference/sdlc/code.playbook/code.fsm.introspect.js +61 -66
- package/reference/sdlc/code.playbook/code.fsm.introspect.ts +100 -149
- package/reference/sdlc/code.playbook/code.fsm.js +587 -1347
- package/reference/sdlc/code.playbook/code.fsm.ts +809 -1650
- package/reference/sdlc/code.playbook/code.gears.md +51 -263
- package/reference/sdlc/code.playbook/code.playbook.d.ts +8 -47
- package/reference/sdlc/code.playbook/code.playbook.js +69 -639
- package/reference/sdlc/code.playbook/code.playbook.ts +90 -850
- package/reference/sdlc/code.playbook/code.registry.d.ts +9 -25
- package/reference/sdlc/code.playbook/code.registry.js +20 -78
- package/reference/sdlc/code.playbook/code.registry.ts +58 -122
- package/reference/sdlc/code.playbook/playbook-captain.d.ts +2 -0
- package/reference/sdlc/code.playbook/playbook-captain.js +1877 -251
- package/reference/sdlc/code.playbook/playbook-captain.ts +2385 -352
- package/reference/sdlc/code.playbook/playbook.config.template.yaml +33 -22
- package/reference/sdlc/decide.md +54 -0
- package/reference/sdlc/decide.playbook/decide.fsm.d.ts +261 -0
- package/reference/sdlc/decide.playbook/decide.fsm.js +894 -0
- package/reference/sdlc/decide.playbook/decide.fsm.ts +1152 -0
- package/reference/sdlc/decide.playbook/decide.gears.md +88 -0
- package/reference/sdlc/decide.playbook/decide.playbook.d.ts +67 -0
- package/reference/sdlc/{discuss.playbook/discuss.playbook.js → decide.playbook/decide.playbook.js} +511 -370
- package/reference/sdlc/{discuss.playbook/discuss.playbook.ts → decide.playbook/decide.playbook.ts} +616 -451
- package/reference/sdlc/decide.playbook/decide.registry.d.ts +41 -0
- package/reference/sdlc/decide.playbook/decide.registry.js +60 -0
- package/reference/sdlc/decide.playbook/decide.registry.ts +125 -0
- package/reference/sdlc/review.md +81 -0
- package/reference/sdlc/review.playbook/review.fsm.d.ts +183 -0
- package/reference/sdlc/review.playbook/review.fsm.js +524 -0
- package/reference/sdlc/review.playbook/review.fsm.ts +652 -0
- package/reference/sdlc/review.playbook/review.gears.md +112 -0
- package/reference/sdlc/review.playbook/review.playbook.d.ts +12 -0
- package/reference/sdlc/review.playbook/review.playbook.js +112 -0
- package/reference/sdlc/review.playbook/review.playbook.ts +201 -0
- package/reference/sdlc/review.playbook/review.registry.d.ts +43 -0
- package/reference/sdlc/review.playbook/review.registry.js +73 -0
- package/reference/sdlc/review.playbook/review.registry.ts +138 -0
- package/slc/gears2fsm.md +67 -6
- package/slc/link.md +339 -25
- package/slc/text2gears.md +22 -2
- package/src/runtime.d.ts +36 -1
- package/src/runtime.ts +59 -0
- package/src/xstate-playbook-runtime.d.ts +96 -7
- package/src/xstate-playbook-runtime.js +1018 -49
- package/src/xstate-playbook-runtime.ts +1283 -59
- package/src/xstate-runtime.js +25 -0
- package/src/xstate-runtime.ts +51 -0
- package/reference/sdlc/discuss.md +0 -93
- package/reference/sdlc/discuss.playbook/discuss.fsm.d.ts +0 -396
- package/reference/sdlc/discuss.playbook/discuss.fsm.js +0 -2067
- package/reference/sdlc/discuss.playbook/discuss.fsm.ts +0 -2465
- package/reference/sdlc/discuss.playbook/discuss.gears.md +0 -258
- package/reference/sdlc/discuss.playbook/discuss.playbook.d.ts +0 -113
- package/reference/sdlc/discuss.playbook/discuss.registry.d.ts +0 -58
- package/reference/sdlc/discuss.playbook/discuss.registry.js +0 -97
- package/reference/sdlc/discuss.playbook/discuss.registry.ts +0 -153
package/slc/text2gears.md
CHANGED
|
@@ -65,6 +65,20 @@ Those requirements remain in the item's condition or `Results:` metadata.
|
|
|
65
65
|
Adding control-oriented prompt lines merely to restate them changes the
|
|
66
66
|
Boss-visible contract and is nonconformant.
|
|
67
67
|
|
|
68
|
+
### Authored prompt fragments
|
|
69
|
+
|
|
70
|
+
Source may compose one acting prompt from authored Markdown instruction blocks and runtime context that it explicitly says to relay in quotes (`>`).
|
|
71
|
+
A fenced `markdown` block introduced as an instruction or prompt is an authored static prompt fragment: its fence delimiters are Source syntax, while every interior line and blank line is prompt content preserved after documented Markdown unescaping.
|
|
72
|
+
|
|
73
|
+
An instruction fence and a relayed-context fragment that apply to one behavior shall appear in the target blockquote in their Source order.
|
|
74
|
+
Distinct non-empty fragments shall be separated by one blank prompt line unless Source explicitly supplies a different boundary.
|
|
75
|
+
text2gears shall not move a shared instruction ahead of behavior-specific context, move quoted evidence after an instruction that Source says follows the evidence, or otherwise regroup fragments for convenience.
|
|
76
|
+
|
|
77
|
+
Where Source says that a runtime value is relayed in quotes, the leading `>` is prompt content rather than Source-only blockquote syntax.
|
|
78
|
+
If Source supplies a blockquoted template for that relay, text2gears shall keep one literal leading `>` on every quoted line; the target GEARS line therefore uses its outer blockquote marker followed by the literal marker, such as `> > Coder output: <coder-output>`.
|
|
79
|
+
If Source names the relayed value but supplies no template, text2gears shall emit its canonical typed placeholder on a line beginning with literal `> ` and shall not summarize, paraphrase, or invent a value in its place.
|
|
80
|
+
An ordinary Source blockquote that specifies a complete acting prompt without requiring quoted relay retains the existing rule above: its one leading marker is Source syntax and is not prompt content.
|
|
81
|
+
|
|
68
82
|
Source statements that assign active-leaf routing, call identity, suspension,
|
|
69
83
|
or return matching to the host describe execution preconditions rather than
|
|
70
84
|
behaviors for Captain to perform. text2gears shall use such a statement only as
|
|
@@ -139,6 +153,11 @@ A single-outcome producer then declares exactly one bullet naming the
|
|
|
139
153
|
property; this consumed-output case is the sole one in which a
|
|
140
154
|
single-outcome behavior carries a `Results:` label.
|
|
141
155
|
|
|
156
|
+
Where a later prompt relays a delegated player's whole final response as quoted context, the producer shall declare that property in the exact annotated form `` `<field>: <verbatim final text>` ``.
|
|
157
|
+
The annotation makes the field runtime-owned: the adjudicator selects the result guard, while the linked runtime carries the player's canonical final text into that field instead of asking a judge to reproduce it.
|
|
158
|
+
A distinct typed field extracted from that response remains judge-authored even when a later prompt quotes its exact value; quoting a field does not turn it into the player's whole final response.
|
|
159
|
+
One property name shall not be annotated as verbatim in one result contract and judge-authored in another; text2gears shall choose distinct properties or report that the Source cannot be represented by the current contract.
|
|
160
|
+
|
|
142
161
|
Result metadata is compiler control data, not part of the acting agent's
|
|
143
162
|
prompt.
|
|
144
163
|
text2gears shall not put guard names, result-property schema, JSON control
|
|
@@ -202,11 +221,11 @@ next phase cannot compile.
|
|
|
202
221
|
Example:
|
|
203
222
|
|
|
204
223
|
```markdown
|
|
205
|
-
###
|
|
224
|
+
### DECIDE-1
|
|
206
225
|
|
|
207
226
|
Parallel group: initial-proposals
|
|
208
227
|
|
|
209
|
-
When Boss gives a topic, Captain shall prompt
|
|
228
|
+
When Boss gives a topic, Captain shall prompt Coder:
|
|
210
229
|
|
|
211
230
|
> Propose your design independently.
|
|
212
231
|
```
|
|
@@ -306,6 +325,7 @@ Prompts shall carry the specification's normative requirements as instructions t
|
|
|
306
325
|
|
|
307
326
|
Source snippets may overlap or duplicate.
|
|
308
327
|
When composing them into a spec item, text2gears shall deduplicate identical prompt lines.
|
|
328
|
+
It shall not deduplicate across distinct authored fragments when doing so would erase a fragment boundary or change the Source-ordered prompt.
|
|
309
329
|
|
|
310
330
|
Each spec item addresses one state behavior and carries its full final prompt (the static part).
|
|
311
331
|
Cross-item duplication is acceptable: spec items are compiled artifacts; Source is what users maintain.
|
package/src/runtime.d.ts
CHANGED
|
@@ -7,6 +7,12 @@ export interface PlayerResult {
|
|
|
7
7
|
export interface PlayerCallOptions {
|
|
8
8
|
resume: string | false;
|
|
9
9
|
}
|
|
10
|
+
export interface PlayerSessionStore {
|
|
11
|
+
select(playerId: string): string | false;
|
|
12
|
+
update(playerId: string, resumeToken?: string): void;
|
|
13
|
+
snapshot(): Readonly<Record<string, string>>;
|
|
14
|
+
restore(tokens: Readonly<Record<string, string>>): void;
|
|
15
|
+
}
|
|
10
16
|
export interface CaptainCallOptions {
|
|
11
17
|
visibility: 'visible' | 'hidden';
|
|
12
18
|
resume: string | false;
|
|
@@ -106,9 +112,10 @@ export interface PlaybookSession {
|
|
|
106
112
|
parentSessionId?: string;
|
|
107
113
|
parentCallId?: string;
|
|
108
114
|
depth: number;
|
|
115
|
+
playerSessions?: PlayerSessionStore;
|
|
109
116
|
ports: PlaybookPorts;
|
|
110
117
|
}
|
|
111
|
-
export type PlaybookTraceType = 'session.started' | 'boss.input.received' | 'judge.call.started' | 'judge.call.finished' | 'player.call.started' | 'player.call.finished' | 'captain.call.started' | 'captain.call.finished' | 'playbook.call.started' | 'playbook.call.finished' | 'fsm.transition' | 'status.emitted' | 'boss.input.settled' | 'session.disposed';
|
|
118
|
+
export type PlaybookTraceType = 'session.started' | 'boss.input.received' | 'judge.call.started' | 'judge.call.finished' | 'player.call.started' | 'player.call.finished' | 'captain.call.started' | 'captain.call.finished' | 'playbook.call.started' | 'playbook.call.finished' | 'apply.started' | 'apply.finished' | 'fsm.transition' | 'status.emitted' | 'boss.input.settled' | 'session.disposed';
|
|
112
119
|
export interface PlaybookTraceEvent {
|
|
113
120
|
schemaVersion: 2;
|
|
114
121
|
sessionId: string;
|
|
@@ -148,10 +155,38 @@ export interface PlaybookRuntimeSnapshot {
|
|
|
148
155
|
state: PlaybookState;
|
|
149
156
|
pendingBossQuestions: readonly PlaybookPendingBossQuestion[];
|
|
150
157
|
}
|
|
158
|
+
export interface PlaybookControlAction {
|
|
159
|
+
id: string;
|
|
160
|
+
label: string;
|
|
161
|
+
}
|
|
162
|
+
export interface PlaybookControlView {
|
|
163
|
+
state: PlaybookState;
|
|
164
|
+
stateDescription?: string;
|
|
165
|
+
context?: JsonValue;
|
|
166
|
+
pendingQuestions: readonly PlaybookPendingBossQuestion[];
|
|
167
|
+
lastError?: NormalizedError;
|
|
168
|
+
actions: readonly PlaybookControlAction[];
|
|
169
|
+
}
|
|
170
|
+
export type PlaybookControlReceipt = {
|
|
171
|
+
disposition: 'rejected';
|
|
172
|
+
reason: string;
|
|
173
|
+
} | {
|
|
174
|
+
disposition: 'executed';
|
|
175
|
+
run: PlaybookRunResult;
|
|
176
|
+
} | {
|
|
177
|
+
disposition: 'failed';
|
|
178
|
+
error: NormalizedError;
|
|
179
|
+
};
|
|
151
180
|
export interface PlaybookRuntime {
|
|
152
181
|
init(session: PlaybookSession): Promise<void>;
|
|
153
182
|
exportSnapshot?(): PlaybookRuntimeSnapshot | undefined;
|
|
154
183
|
restore?(session: PlaybookSession, snapshot: PlaybookRuntimeSnapshot): Promise<void>;
|
|
184
|
+
describe?(): PlaybookControlView;
|
|
185
|
+
apply?(input: {
|
|
186
|
+
actionId: string;
|
|
187
|
+
key: string;
|
|
188
|
+
signal: AbortSignal;
|
|
189
|
+
}): Promise<PlaybookControlReceipt>;
|
|
155
190
|
handleBossInput(turn: {
|
|
156
191
|
text: string;
|
|
157
192
|
signal: AbortSignal;
|
package/src/runtime.ts
CHANGED
|
@@ -19,6 +19,17 @@ export interface PlayerCallOptions {
|
|
|
19
19
|
resume: string | false;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
// DR-030: a composing host may supply one frame-local view of the root
|
|
23
|
+
// engagement's player continuation. The runtime selects through this store
|
|
24
|
+
// before tracing/calling and updates it from the validated result. Hosts that
|
|
25
|
+
// omit it retain the runtime's private per-session store.
|
|
26
|
+
export interface PlayerSessionStore {
|
|
27
|
+
select(playerId: string): string | false;
|
|
28
|
+
update(playerId: string, resumeToken?: string): void;
|
|
29
|
+
snapshot(): Readonly<Record<string, string>>;
|
|
30
|
+
restore(tokens: Readonly<Record<string, string>>): void;
|
|
31
|
+
}
|
|
32
|
+
|
|
22
33
|
export interface CaptainCallOptions {
|
|
23
34
|
visibility: 'visible' | 'hidden';
|
|
24
35
|
resume: string | false;
|
|
@@ -143,6 +154,7 @@ export interface PlaybookSession {
|
|
|
143
154
|
parentSessionId?: string;
|
|
144
155
|
parentCallId?: string;
|
|
145
156
|
depth: number;
|
|
157
|
+
playerSessions?: PlayerSessionStore;
|
|
146
158
|
ports: PlaybookPorts;
|
|
147
159
|
}
|
|
148
160
|
|
|
@@ -157,6 +169,8 @@ export type PlaybookTraceType =
|
|
|
157
169
|
| 'captain.call.finished'
|
|
158
170
|
| 'playbook.call.started'
|
|
159
171
|
| 'playbook.call.finished'
|
|
172
|
+
| 'apply.started'
|
|
173
|
+
| 'apply.finished'
|
|
160
174
|
| 'fsm.transition'
|
|
161
175
|
| 'status.emitted'
|
|
162
176
|
| 'boss.input.settled'
|
|
@@ -206,6 +220,38 @@ export interface PlaybookRuntimeSnapshot {
|
|
|
206
220
|
pendingBossQuestions: readonly PlaybookPendingBossQuestion[];
|
|
207
221
|
}
|
|
208
222
|
|
|
223
|
+
// DR-029: one currently valid, runtime-advertised control action. The id
|
|
224
|
+
// is stable within the returned view; the label is runtime-written,
|
|
225
|
+
// Boss-appropriate text derived from source state descriptions.
|
|
226
|
+
export interface PlaybookControlAction {
|
|
227
|
+
id: string;
|
|
228
|
+
label: string;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// DR-029: the sanitized control view `describe()` returns — current
|
|
232
|
+
// state and the runtime-written description of what that state means,
|
|
233
|
+
// the authored context projection, pending Boss questions, the last
|
|
234
|
+
// recorded error, and the currently valid actions. `stateDescription` is
|
|
235
|
+
// the Boss-appropriate grounding a host may speak from; the state id is
|
|
236
|
+
// internal and is absent from it whenever the runtime's source declares
|
|
237
|
+
// no description for the state it is in.
|
|
238
|
+
export interface PlaybookControlView {
|
|
239
|
+
state: PlaybookState;
|
|
240
|
+
stateDescription?: string;
|
|
241
|
+
context?: JsonValue;
|
|
242
|
+
pendingQuestions: readonly PlaybookPendingBossQuestion[];
|
|
243
|
+
lastError?: NormalizedError;
|
|
244
|
+
actions: readonly PlaybookControlAction[];
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// DR-029: the receipt `apply()` returns says which of three things
|
|
248
|
+
// happened — rejected before any effect, executed with the settled run
|
|
249
|
+
// result, or failed after effects may exist.
|
|
250
|
+
export type PlaybookControlReceipt =
|
|
251
|
+
| { disposition: 'rejected'; reason: string }
|
|
252
|
+
| { disposition: 'executed'; run: PlaybookRunResult }
|
|
253
|
+
| { disposition: 'failed'; error: NormalizedError };
|
|
254
|
+
|
|
209
255
|
export interface PlaybookRuntime {
|
|
210
256
|
init(session: PlaybookSession): Promise<void>;
|
|
211
257
|
// DR-014 §1 optional durable-session capability: a runtime implements
|
|
@@ -218,6 +264,19 @@ export interface PlaybookRuntime {
|
|
|
218
264
|
session: PlaybookSession,
|
|
219
265
|
snapshot: PlaybookRuntimeSnapshot,
|
|
220
266
|
): Promise<void>;
|
|
267
|
+
// DR-029 optional control-surface capability: a runtime implements
|
|
268
|
+
// both members or neither. `describe` is side-effect free and valid at
|
|
269
|
+
// parked quiescence outside an active boundary; `apply` revalidates the
|
|
270
|
+
// named action against the live state, executes it at most once per
|
|
271
|
+
// idempotency key within that runtime instance, and returns a receipt. A
|
|
272
|
+
// runtime lacking the pair advertises no actions; plain text delivery is
|
|
273
|
+
// the only verb against it.
|
|
274
|
+
describe?(): PlaybookControlView;
|
|
275
|
+
apply?(input: {
|
|
276
|
+
actionId: string;
|
|
277
|
+
key: string;
|
|
278
|
+
signal: AbortSignal;
|
|
279
|
+
}): Promise<PlaybookControlReceipt>;
|
|
221
280
|
handleBossInput(turn: {
|
|
222
281
|
text: string;
|
|
223
282
|
signal: AbortSignal;
|
|
@@ -48,12 +48,30 @@ export type JudgePurpose = 'boss-input-classification' | 'player-output-adjudica
|
|
|
48
48
|
export interface RuntimeBoundaryCalls {
|
|
49
49
|
callPlayer(input: PlaybookPlayerInput, playerId: string, prompt: string, signal: AbortSignal): Promise<PlayerResult>;
|
|
50
50
|
callJudge(purpose: JudgePurpose, stateId: string | undefined, prompt: string, signal: AbortSignal): Promise<string>;
|
|
51
|
-
callCaptain?(input: PlaybookCaptainInput, prompt: string, signal: AbortSignal): Promise<CaptainResult>;
|
|
51
|
+
callCaptain?(input: PlaybookCaptainInput, prompt: string, signal: AbortSignal, callOptions?: XStateCaptainCallOptions): Promise<CaptainResult>;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Presentation selection for one traced direct-Captain call
|
|
55
|
+
* (slc/link.md §Captain adjudication). `'visible'` (the default) is the
|
|
56
|
+
* workflow form: the port receives `{ visibility: 'visible', resume: false }`
|
|
57
|
+
* and the trace pair carries both members. `'hidden'` is the controller form
|
|
58
|
+
* (DR-029): the port receives `{ visibility: 'hidden', resume: false }`
|
|
59
|
+
* while the host's session-Captain wrapper owns the actual durable-conversation
|
|
60
|
+
* resume selection, so the trace pair carries `visibility: 'hidden'` and no
|
|
61
|
+
* `resume` member — the pinned token never enters runtime telemetry.
|
|
62
|
+
*/
|
|
63
|
+
export interface XStateCaptainCallOptions {
|
|
64
|
+
visibility?: 'visible' | 'hidden';
|
|
52
65
|
}
|
|
53
66
|
export interface ScheduledStatus {
|
|
54
67
|
message: string;
|
|
55
68
|
data?: JsonValue;
|
|
56
69
|
}
|
|
70
|
+
/** Boss-facing identity for one FSM state whose invoked actor is `player`. */
|
|
71
|
+
export interface XStatePlayerStateStatus {
|
|
72
|
+
player: string;
|
|
73
|
+
label: string;
|
|
74
|
+
}
|
|
57
75
|
export interface XStateBossEventFieldSpec {
|
|
58
76
|
/** The judge supplies routing data; the runtime supplies exact Boss text. */
|
|
59
77
|
source: 'judge' | 'text';
|
|
@@ -81,6 +99,46 @@ export interface XStatePlaybookRuntimeCompat {
|
|
|
81
99
|
/** The engine ABI the artifact was linked against. */
|
|
82
100
|
runtimeAbi: number;
|
|
83
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* One direct-Captain actor invocation handed to a spec's `captainStrategy`
|
|
104
|
+
* (slc/link.md §Captain adjudication, controller form). The engine owns
|
|
105
|
+
* signal combination, emission draining, trace pairing, the shared
|
|
106
|
+
* Captain/judge lane, and control-plane latching; the strategy owns the
|
|
107
|
+
* playbook-specific call pipeline — e.g. the controller's hidden decision
|
|
108
|
+
* call, `{ action, … }` control-JSON validation with its single corrective
|
|
109
|
+
* re-ask, and controller-port submission.
|
|
110
|
+
*/
|
|
111
|
+
export interface XStateCaptainStrategyRun<TOptions> {
|
|
112
|
+
input: PlaybookCaptainInput;
|
|
113
|
+
/** The prompt composed by the spec's Captain composer for `input`. */
|
|
114
|
+
prompt: string;
|
|
115
|
+
/** Combined invocation-lifetime + active-boundary abort signal. */
|
|
116
|
+
signal: AbortSignal;
|
|
117
|
+
/** The immutable validated runtime options. */
|
|
118
|
+
options: TOptions;
|
|
119
|
+
/** The bound immutable playbook session identity. */
|
|
120
|
+
session: PlaybookSession;
|
|
121
|
+
/**
|
|
122
|
+
* One traced Captain call through the shared serialized lane; every call —
|
|
123
|
+
* initial or corrective — emits its own paired `captain.call.started` /
|
|
124
|
+
* `captain.call.finished` boundary. Throws the boundary's authoritative
|
|
125
|
+
* failure for non-`ok` and empty-`ok` results exactly as the default
|
|
126
|
+
* pipeline does.
|
|
127
|
+
*/
|
|
128
|
+
callCaptain(prompt: string, callOptions?: XStateCaptainCallOptions): Promise<CaptainResult>;
|
|
129
|
+
/**
|
|
130
|
+
* DR-028: true when `error` is the boundary's re-askable empty-`ok`
|
|
131
|
+
* marker; the strategy may re-issue the same composed call exactly once.
|
|
132
|
+
*/
|
|
133
|
+
isEmptyOkRetry(error: unknown): boolean;
|
|
134
|
+
/**
|
|
135
|
+
* Mark `error` as a recoverable FSM-result failure: it travels the invoked
|
|
136
|
+
* actor's XState `onError` path without being latched as a control-plane
|
|
137
|
+
* error, so the machine's authored recovery arms can route it.
|
|
138
|
+
*/
|
|
139
|
+
recoverableFailure<E extends Error>(error: E): E;
|
|
140
|
+
}
|
|
141
|
+
export type XStateCaptainStrategy<TOptions> = (run: XStateCaptainStrategyRun<TOptions>) => Promise<PlaybookActorOutput>;
|
|
84
142
|
export interface XStatePlaybookRuntimeSpec<TOptions> {
|
|
85
143
|
/** Diagnostic label used in internal invariant errors. Default 'playbook'. */
|
|
86
144
|
label?: string;
|
|
@@ -112,10 +170,22 @@ export interface XStatePlaybookRuntimeSpec<TOptions> {
|
|
|
112
170
|
* the XState machine alone.
|
|
113
171
|
*/
|
|
114
172
|
bossEvents?: readonly XStateBossEventSpec[];
|
|
115
|
-
/** Boss-input classifier override; default: generic parked-state classifier. */
|
|
116
|
-
classifyBossText?: (text: string, ports: PlaybookPorts, signal: AbortSignal, snapshotOrState: unknown, boundary?: RuntimeBoundaryCalls) => Promise<EventObject | undefined>;
|
|
117
|
-
/**
|
|
173
|
+
/** Boss-input classifier override; default: generic parked-state classifier. Receives the bound validated options last so a fully deterministic controller mapping can consult host-supplied option members (slc/link.md §Boss-event mapping). */
|
|
174
|
+
classifyBossText?: (text: string, ports: PlaybookPorts, signal: AbortSignal, snapshotOrState: unknown, boundary?: RuntimeBoundaryCalls, options?: TOptions) => Promise<EventObject | undefined>;
|
|
175
|
+
/**
|
|
176
|
+
* Direct-Captain actor strategy override (slc/link.md §Captain
|
|
177
|
+
* adjudication, controller form): replaces the default visible-call +
|
|
178
|
+
* hidden-judge pipeline for every `captain` state of this machine. The
|
|
179
|
+
* engine still composes the prompt, combines signals, traces each call as
|
|
180
|
+
* its own pair, and latches control-plane errors; failures the strategy
|
|
181
|
+
* marks with `recoverableFailure` travel the actor's `onError` path as
|
|
182
|
+
* recoverable FSM-result failures instead.
|
|
183
|
+
*/
|
|
184
|
+
captainStrategy?: XStateCaptainStrategy<TOptions>;
|
|
185
|
+
/** Status line emitted after classification; canonical metadata defaults to the event type, legacy artifacts to none. */
|
|
118
186
|
classificationStatus?: (event: EventObject) => string | undefined;
|
|
187
|
+
/** Complete FSM-derived Boss-facing metadata for every `player` state; its presence selects the canonical status profile. */
|
|
188
|
+
playerStates?: Readonly<Record<string, XStatePlayerStateStatus>>;
|
|
119
189
|
/** Map a player-invoking state's input to the host player id. Default: lowercased player name. */
|
|
120
190
|
resolvePlayerId?: (input: PlaybookPlayerInput, options: TOptions) => string;
|
|
121
191
|
/** Compose the player prompt. Default: continuation blocks + `<field>` placeholder substitution. */
|
|
@@ -130,9 +200,21 @@ export interface XStatePlaybookRuntimeSpec<TOptions> {
|
|
|
130
200
|
extractRequiredFields?: (description: string) => string[];
|
|
131
201
|
/** Required fields carried verbatim from the player's finalText instead of judge JSON. Default: none. */
|
|
132
202
|
verbatimPayloadFields?: ReadonlySet<string>;
|
|
203
|
+
/**
|
|
204
|
+
* DR-029 / PBRT-52: the runtime-authored ControlView context
|
|
205
|
+
* projection — the exact FSM context members `describe()` may expose,
|
|
206
|
+
* in the order the view lists them. Only this artifact knows which of
|
|
207
|
+
* its context members are safe and relevant for a controller prompt, so
|
|
208
|
+
* the engine exports what is named here and nothing else: a member the
|
|
209
|
+
* artifact has not named stays private, and a member added to the FSM
|
|
210
|
+
* later stays private until someone names it. Absent or empty: the view
|
|
211
|
+
* carries no context at all. `pendingBossQuestion` and `lastError` are
|
|
212
|
+
* surfaced first-class by the view and shall not be named here.
|
|
213
|
+
*/
|
|
214
|
+
controlContextFields?: readonly string[];
|
|
133
215
|
/** States that may suspend for a Boss reply. Default: targets of the FSM's `awaitBossReply` BOSS_REPLY transitions. */
|
|
134
216
|
resumableStateIds?: ReadonlySet<string>;
|
|
135
|
-
/** Human status lines for a root transition. Default:
|
|
217
|
+
/** Human status lines for a root transition. Default: guard, declared-player, question, and failure lines. */
|
|
136
218
|
statusesForState?: (state: PlaybookState, context: Record<string, unknown>, event: unknown) => readonly ScheduledStatus[];
|
|
137
219
|
/** Detached JSON-safe transition-event descriptor. Default: `type` + `transitionEventFields` strings + validated output + normalized error. */
|
|
138
220
|
normalizeTransitionEvent?: (event: unknown) => JsonValue | undefined;
|
|
@@ -215,6 +297,12 @@ export declare function defaultBuildCaptainJudgePrompt(input: {
|
|
|
215
297
|
}, finalText: string): string;
|
|
216
298
|
/** Targets of the FSM's `awaitBossReply` BOSS_REPLY transitions. */
|
|
217
299
|
export declare function resumableStateIdsFromMachine(machine: AnyStateMachine): ReadonlySet<string>;
|
|
300
|
+
/**
|
|
301
|
+
* Source state descriptions by state key, node id, and `meta.playbook`
|
|
302
|
+
* state id, read from `machine.config`. Control actions are labeled from
|
|
303
|
+
* these descriptions (DR-029); a state without one has no entry.
|
|
304
|
+
*/
|
|
305
|
+
export declare function stateDescriptionsFromMachine(machine: AnyStateMachine): ReadonlyMap<string, string>;
|
|
218
306
|
/**
|
|
219
307
|
* Build a `PlaybookRuntimeFactory` that interprets the given FSM artifact
|
|
220
308
|
* under the slc/link.md contract. The factory provides every actor kind the
|
|
@@ -222,7 +310,8 @@ export declare function resumableStateIdsFromMachine(machine: AnyStateMachine):
|
|
|
222
310
|
* (literal and dynamic) — and implements the full runtime lifecycle including
|
|
223
311
|
* the optional parked-session snapshot capability (DR-014).
|
|
224
312
|
*
|
|
225
|
-
* Scope:
|
|
226
|
-
* playbook state id). Parallel-region FSMs keep their own linked
|
|
313
|
+
* Scope: machines that declare no parallel state (each snapshot exposes
|
|
314
|
+
* exactly one playbook state id). Parallel-region FSMs keep their own linked
|
|
315
|
+
* runtimes.
|
|
227
316
|
*/
|
|
228
317
|
export declare function createXStatePlaybookRuntime<TOptions>(machine: AnyStateMachine, spec: XStatePlaybookRuntimeSpec<TOptions>): PlaybookRuntimeFactory<TOptions>;
|