@sublang/playbook 1.0.0 → 1.3.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.
@@ -66,3 +66,14 @@ playbooks:
66
66
  # host: claude-opus
67
67
  # participant: codex-gpt
68
68
  # committer: host
69
+
70
+ # Non-interactive `playbook run` defaults (optional). Each value is an
71
+ # agent string <adapter>[:<model>][@<effort>]; `player` is the catch-all
72
+ # for any required role without its own `players.<role>` entry, across
73
+ # every playbook. Flags override per role (--player / --captain), and
74
+ # `playbook run resume` keeps the lineup stored with the parked session.
75
+ #run:
76
+ # captain: claude:claude-opus-4-8@high
77
+ # player: claude:claude-opus-4-8@high
78
+ # players:
79
+ # coder: claude:claude-opus-4-8[1m]@xhigh
@@ -266,7 +266,7 @@ export declare const discussMachine: import("xstate").StateMachine<DiscussContex
266
266
  } | {
267
267
  type: "mixedReview";
268
268
  params: unknown;
269
- }, never, "done" | "failed" | "ready" | "awaitBossReply" | "hostWritesAgreement" | "commitInitialChanges" | "reviewSpecInitialCommit" | "reviewSpecHostChanges" | "reviewDrInitialCommit" | "reviewDrHostChanges" | "reviewMixedInitialCommit" | "reviewMixedHostChanges" | "hostAddressesFindings" | "participantAddressesRebuttals" | "commitReviewedChanges" | {
269
+ }, never, "done" | "failed" | "awaitBossReply" | "ready" | "hostWritesAgreement" | "commitInitialChanges" | "reviewSpecInitialCommit" | "reviewSpecHostChanges" | "reviewDrInitialCommit" | "reviewDrHostChanges" | "reviewMixedInitialCommit" | "reviewMixedHostChanges" | "hostAddressesFindings" | "participantAddressesRebuttals" | "commitReviewedChanges" | {
270
270
  initialProposalRound: {
271
271
  host: "working" | "waiting" | "complete";
272
272
  participant: "working" | "waiting" | "complete";
package/slc/link.md CHANGED
@@ -779,8 +779,9 @@ independent cleanup evidence.
779
779
  ## Script execution
780
780
 
781
781
  Where the FSM declares the typed `script` actor from
782
- [gears2fsm "Setup"](gears2fsm.md#setup), the linker shall provide its
783
- implementation inside the emitted module.
782
+ [gears2fsm "Setup"](gears2fsm.md#setup), the linked runtime shall provide
783
+ its implementation through the shared factory (§Output); the linker shall
784
+ not regenerate a script executor inside each emitted module.
784
785
  A script invocation is the one actor kind that runs without any agent:
785
786
  it makes no `callPlayer`, `callCaptain`, or `callJudge` call and needs no
786
787
  adjudication.
@@ -791,7 +792,8 @@ The provided actor shall:
791
792
  (`sh -c`), with the working directory taken from the emitted
792
793
  `PlaybookRuntimeOptions.cwd` when the caller supplies it, else the process
793
794
  working directory. The linker shall declare the optional `cwd` option on the
794
- emitted options interface whenever the FSM contains a script state.
795
+ emitted options interface whenever the FSM contains a script state; the
796
+ validated option reaches the shared script actor through the spec.
795
797
  - Resolve deterministically from the child's exit status: status zero resolves
796
798
  `{ guard: <first declared guard>, exitStatus: 0 }`; any nonzero status
797
799
  resolves the second declared guard with that status. Guard selection is
@@ -816,9 +818,9 @@ them in machine context, prompts, or trace payloads.
816
818
 
817
819
  Where the FSM declares the typed `playbook` actor from
818
820
  [gears2fsm](gears2fsm.md#nested-playbook-calls), the linked runtime shall provide
819
- it with the shared `createNestedPlaybookBridge(...).actorLogic`; it shall not
820
- regenerate a second pending-call, identity-validation, or abort-cleanup
821
- substrate inside each linked artifact.
821
+ it with the shared `createNestedPlaybookBridge(...).actorLogic` wired by the
822
+ shared factory per §Output — and shall not regenerate a second pending-call,
823
+ identity-validation, or abort-cleanup substrate inside each linked artifact.
822
824
  Instantiate the generic bridge with the FSM-exported `PlaybookInput` type so
823
825
  XState `.provide(...)` receives the exact declared actor input rather than a
824
826
  structurally similar local type.
@@ -1122,7 +1124,9 @@ At a safe capture point it shall return a JSON-safe
1122
1124
  - `playerResumeTokens`: the resume-token map as a plain object
1123
1125
  (§PlaybookPorts contract).
1124
1126
  - `sequences`: the live `trace`, `turn`, `judgeCall`, `playerCall`, and
1125
- `playbookCall` counters.
1127
+ `playbookCall` counters, plus `captainCall` when the runtime supports direct
1128
+ Captain calls. `captainCall` remains optional under schema version `1` for
1129
+ backward compatibility; a direct-Captain-capable runtime shall persist it.
1126
1130
  - `state`: the current normalized state descriptor.
1127
1131
  - `pendingBossQuestions`: the pending Boss question(s) from FSM context as
1128
1132
  a list of `{ questionId, player, question, sourceItem? }`, empty when the
@@ -1141,7 +1145,9 @@ module identity — that the factory constructing this runtime still
1141
1145
  belongs to the snapshot's playbook — is likewise the host's check to
1142
1146
  make before calling `restore`.
1143
1147
  `restore` shall bind the session, restore the resume-token map, the
1144
- sequence counters, and the prior-state descriptor from the snapshot,
1148
+ sequence counters (using the persisted global `trace` counter as a
1149
+ collision-safe floor for an absent legacy `captainCall`), and the
1150
+ prior-state descriptor from the snapshot,
1145
1151
  construct the actor with the persisted `machine` snapshot, and start it
1146
1152
  with root inspection emissions suppressed so rehydration emits no
1147
1153
  `session.started` trace, no transition trace, and no human status — the
@@ -1227,7 +1233,19 @@ The `playbook.trace` copies are the host-agnostic runtime-boundary record requir
1227
1233
 
1228
1234
  ## Output
1229
1235
 
1230
- The link compiler emits **one** TypeScript module that:
1236
+ The link compiler emits **one thin** TypeScript module per playbook.
1237
+ The FSM-interpreter machinery — actor wiring, boundary tracing, Boss-event
1238
+ mapping, adjudication, script execution, nested-playbook bridging, session
1239
+ lifecycle, abort handling, and the optional parked-session snapshot
1240
+ capability — is not regenerated per artifact: it ships once as the shared
1241
+ `createXStatePlaybookRuntime(machine, spec)` factory exported by
1242
+ `@sublang/playbook/xstate-runtime`, and the emitted module hands its FSM and
1243
+ a small per-playbook `spec` to that factory. Every behavioral section of
1244
+ this definition still binds the emitted module's runtime; the shared factory
1245
+ is how the emitted module satisfies them, so a runtime fix ships as a
1246
+ package release instead of a re-link of every artifact.
1247
+
1248
+ The emitted module:
1231
1249
 
1232
1250
  - Imports the FSM artifact by relative path with an extension-bearing
1233
1251
  runtime specifier. When the linked TypeScript is part of a package that
@@ -1240,34 +1258,75 @@ The link compiler emits **one** TypeScript module that:
1240
1258
  that strip cleanly, no constructor parameter properties, `enum`s, or
1241
1259
  namespaces — so a host running under type stripping loads it
1242
1260
  directly.
1243
- - Imports XState's actor primitives (`createActor`, `fromPromise`,
1244
- `setup`'s `.provide`).
1245
- - Imports `PQueue` from `p-queue` for its single serialized emission channel.
1246
- - Imports the FSM's exported machine/actor input and output types and uses
1247
- those exact types in `.provide(...)`; it shall not redeclare look-alike
1248
- Captain, player, playbook, question, or output contracts beside the linked
1249
- runtime.
1250
- - Imports the applicable shared helpers from the extension-bearing
1251
- `xstate-runtime.js` sibling of the resolved shared `--link` contract module,
1252
- with that sibling path relativized from the emitted artifact exactly as the
1253
- contract import is. Every runtime uses `assertJsonSafe`, `snapshotJsonValue`,
1254
- `snapshotPlaybookSession`, `normalizeError`,
1255
- `normalizePlaybookSnapshot`, and `waitForPlaybookQuiescence`; it additionally
1256
- imports `combineAbortSignals`, result validators, and
1257
- `createNestedPlaybookBridge` only when its actor and composition paths need
1258
- them. It shall use those helpers instead of emitting weaker local JSON,
1259
- error, snapshot, nested-call, or imperative-wait implementations.
1260
- - Exports `createPlaybookRuntime` and the typed `PlaybookRuntimeOptions`
1261
- interface for that playbook.
1261
+ - Imports `createXStatePlaybookRuntime` (plus any shared strategy defaults
1262
+ its `_internal` surface re-exports) from the shared engine module through
1263
+ its bare package specifier `@sublang/playbook/xstate-runtime`, and the
1264
+ contract types through `@sublang/playbook/runtime`. It shall not copy,
1265
+ inline, or re-derive interpreter machinery actor bridges, trace
1266
+ emission, judge-JSON recovery, lifecycle guards beside the factory
1267
+ call, and shall not import `xstate`, `p-queue`, or `node:child_process`
1268
+ itself; those are the shared engine's dependencies.
1269
+ - Declares and exports the typed `PlaybookRuntimeOptions` interface for that
1270
+ playbook, derived from every required FSM input field that is not supplied
1271
+ by `PlaybookSession` or another linker-owned source (§PlaybookRuntime
1272
+ contract), plus the optional `cwd` option whenever the FSM contains a
1273
+ `script` state (§Script execution).
1274
+ - Supplies the spec's `snapshotOptions` with the same options-validation
1275
+ semantics previously generated inline: validate and JSON-snapshot the
1276
+ caller's options, rejecting undeclared keys and non-conforming values, so
1277
+ the factory binds an immutable options record before constructing any
1278
+ actor.
1279
+ - Supplies in `spec` only what the factory cannot read from the FSM
1280
+ artifact's own data: the deterministic textual entry event where
1281
+ §Boss-event mapping prescribes deterministic entry; compact `bossEvents`
1282
+ metadata for each additional Boss-union arm whose exact required/optional
1283
+ judge fields, runtime-owned text fields, or closed string values disappear
1284
+ under TypeScript erasure; `placeholderFields` only for authored token/field
1285
+ exceptions not covered by the canonical kebab-token-to-camel-field mapping
1286
+ and the canonical `<#>` → `irNumber` special case; the
1287
+ transition-event payload fields the FSM's Boss union declares; a
1288
+ non-default player binding where the linker inputs supplied one; and any
1289
+ per-playbook strategy override (classifier, prompt composers,
1290
+ required-field extraction, status formatting) an earlier section of this
1291
+ definition requires for that playbook. The metadata shall keep the shared
1292
+ classifier's reply contract exactly flat `{ type, ...declaredFields }` and
1293
+ distinguish judge-authored routing fields from exact-text fields the
1294
+ runtime attaches itself. Everything else — player/script/captain/nested actor
1295
+ provisioning, prompt composition, classification, adjudication, statuses,
1296
+ resumable-state derivation — comes from the factory's generic defaults,
1297
+ which implement the behavioral sections of this definition.
1298
+
1299
+ ```ts
1300
+ interface XStateBossEventFieldSpec {
1301
+ source: 'judge' | 'text';
1302
+ required?: boolean;
1303
+ values?: readonly string[];
1304
+ }
1305
+
1306
+ interface XStateBossEventSpec {
1307
+ type: string;
1308
+ fields?: Readonly<Record<string, XStateBossEventFieldSpec>>;
1309
+ }
1310
+
1311
+ bossEvents?: readonly XStateBossEventSpec[];
1312
+ placeholderFields?: Readonly<Record<string, string>>;
1313
+ ```
1314
+
1315
+ Supplied `bossEvents` metadata shall merge with, and shall not replace or
1316
+ weaken, runtime-derived entry text ownership or closed interrupt targets.
1317
+ A conflicting duplicate field contract is a linker/runtime construction
1318
+ error.
1319
+ - Default-exports the factory call as `createPlaybookRuntime`, typed
1320
+ `PlaybookRuntimeFactory<PlaybookRuntimeOptions>`.
1262
1321
  - Exposes, under an `_internal` export, the pure helpers verification
1263
1322
  needs — at least the player-prompt and Captain-prompt composers
1264
- (`composePlayerPrompt` and `composeCaptainPrompt`) so
1323
+ (`composePlayerPrompt` and `composeCaptainPrompt`), which may re-export
1324
+ the shared defaults when the spec does not override composition — so
1265
1325
  compilation-correctness tests can exercise composition without a host.
1266
1326
  - Holds no host-specific types and no host primitive calls. The runtime
1267
- speaks only `PlaybookPorts` for every agent and host concern; the sole
1268
- exception is `node:child_process`, imported only when the FSM declares a
1269
- `script` actor, so §Script execution can run its deterministic commands
1270
- locally.
1327
+ speaks only `PlaybookPorts` for every agent and host concern; the
1328
+ `node:child_process` dependency of §Script execution lives in the shared
1329
+ factory, not in the emitted module.
1271
1330
  - Records the linker inputs (FSM path, player binding, strategies) in a
1272
1331
  top-of-file header comment so the file is reproducible from the same
1273
1332
  inputs.
@@ -1276,12 +1335,12 @@ The link compiler emits **one** TypeScript module that:
1276
1335
  `PlaybookTraceEvent`,
1277
1336
  `PlaybookCallRequest`, `PlaybookCallResult`, `PlaybookCallStart`,
1278
1337
  `PlaybookStateValue`, `PlaybookState`, `PlaybookRunResult`,
1279
- `PlaybookRuntime`, `PlaybookRuntimeFactory`) from a single shared
1338
+ `PlaybookRuntime`, `PlaybookRuntimeFactory`) from the single shared
1280
1339
  type-only module instead of redefining them, and re-exports the names
1281
1340
  its consumers import, so every linked playbook shares one contract
1282
- definition. The shared module imports no FSM or host types, so the
1341
+ definition. The shared modules import no FSM or host types, so the
1283
1342
  dependency runs one way — from each linked module to the shared
1284
- contract, never the reverse.
1343
+ engine and contract, never the reverse.
1285
1344
 
1286
1345
  When a co-located integration test for the linked runtime already exists, the
1287
1346
  link compiler shall run it before reporting success and treat any failure as a
package/slc/optimize.md CHANGED
@@ -56,9 +56,9 @@ For each eligible item, the pass shall:
56
56
 
57
57
  - Keep the item's ID, heading form, and condition text unchanged.
58
58
  - Replace the acting clause with the literal script form `Captain shall run:`.
59
- Like guard names, the script clause is fixed machine syntax and stays in
60
- this exact English form even when the surrounding item text is in another
61
- language.
59
+ Like guard names, the script clause is fixed machine syntax [[1]] and
60
+ stays in this exact English form even when the surrounding item text is
61
+ in another language.
62
62
  - Replace the blockquoted prompt with the exact POSIX shell script that
63
63
  performs the behavior, static text only.
64
64
  - Emit exactly two `Results:` bullets per
@@ -86,3 +86,7 @@ with no `## Optimizations` section.
86
86
  - Reordering, merging, splitting, or deleting items.
87
87
  - Any change to prompts, conditions, or result contracts of items the pass
88
88
  does not rewrite.
89
+
90
+ ## References
91
+
92
+ [1]: GEARS definition shipped by the installed `@sublang/spex` package: `@sublang/spex/scaffold/specs/meta.md` (English) and `@sublang/spex/scaffold/i18n/zh/specs/meta.md` (Chinese); canonical renditions [GEARS: AI-Ready Spec Syntax](https://sublang.ai/ref/gears-ai-ready-spec-syntax) (en) and [GEARS:面向 AI 的规约语法](https://sublang.ai/zh/ref/gears-ai-ready-spec-syntax) (zh)
package/slc/text2gears.md CHANGED
@@ -287,7 +287,13 @@ Results:
287
287
  - `failed`: The command exited with a nonzero status.
288
288
  ```
289
289
 
290
- Target should be written in the same language as Source.
290
+ Target shall be written in the same language as Source: an item's condition
291
+ prose, acting prompts, and result descriptions follow the Source language,
292
+ read per the matching localization of the GEARS definition [[1]].
293
+ The four `Captain shall` acting-clause forms defined above (direct,
294
+ delegated, nested playbook call, and script), guard names, and the
295
+ `Players:` and `Results:` labels are fixed machine syntax and stay in this
296
+ exact English form regardless of Source language.
291
297
 
292
298
  ## Transformation-spec sources
293
299
 
@@ -324,4 +330,4 @@ Dead branches mislead readers and downstream phases.
324
330
 
325
331
  ## References
326
332
 
327
- [1]: [GEARS syntax](/specs/meta.md#item-syntax)
333
+ [1]: GEARS definition shipped by the installed `@sublang/spex` package: `@sublang/spex/scaffold/specs/meta.md` (English) and `@sublang/spex/scaffold/i18n/zh/specs/meta.md` (Chinese); canonical renditions [GEARS: AI-Ready Spec Syntax](https://sublang.ai/ref/gears-ai-ready-spec-syntax) (en) and [GEARS:面向 AI 的规约语法](https://sublang.ai/zh/ref/gears-ai-ready-spec-syntax) (zh)
package/src/runtime.d.ts CHANGED
@@ -143,6 +143,7 @@ export interface PlaybookRuntimeSnapshot {
143
143
  judgeCall: number;
144
144
  playerCall: number;
145
145
  playbookCall: number;
146
+ captainCall?: number;
146
147
  };
147
148
  state: PlaybookState;
148
149
  pendingBossQuestions: readonly PlaybookPendingBossQuestion[];
package/src/runtime.ts CHANGED
@@ -200,6 +200,7 @@ export interface PlaybookRuntimeSnapshot {
200
200
  judgeCall: number;
201
201
  playerCall: number;
202
202
  playbookCall: number;
203
+ captainCall?: number;
203
204
  };
204
205
  state: PlaybookState;
205
206
  pendingBossQuestions: readonly PlaybookPendingBossQuestion[];
@@ -0,0 +1,201 @@
1
+ import type { AnyStateMachine, EventObject, PromiseActorLogic } from 'xstate';
2
+ import type { CaptainResult, JsonValue, PlaybookPorts, PlaybookRuntimeFactory, PlaybookSession, PlaybookState, PlayerResult } from './runtime.js';
3
+ export interface PlaybookPendingBossQuestionContext {
4
+ questionId: string;
5
+ resumeStateId: string;
6
+ sourceItem: string;
7
+ player: string;
8
+ question: string;
9
+ }
10
+ export interface PlaybookPlayerInput {
11
+ stateId: string;
12
+ player: string;
13
+ sourceItem: string;
14
+ prompt: string;
15
+ result: Readonly<Record<string, string>>;
16
+ pendingBossQuestion?: {
17
+ readonly question: string;
18
+ };
19
+ bossReply?: string;
20
+ }
21
+ export interface PlaybookCaptainInput {
22
+ stateId: string;
23
+ sourceItem: string;
24
+ prompt: string;
25
+ result: Readonly<Record<string, string>>;
26
+ allowedTools?: readonly string[];
27
+ pendingBossQuestion?: {
28
+ readonly question: string;
29
+ };
30
+ bossReply?: string;
31
+ }
32
+ export interface PlaybookScriptInput {
33
+ stateId: string;
34
+ sourceItem: string;
35
+ command: string;
36
+ result: Readonly<Record<string, string>>;
37
+ }
38
+ /** Adjudicated actor output: the selected guard plus payload fields. */
39
+ export type PlaybookActorOutput = Record<string, unknown> & {
40
+ guard: string;
41
+ };
42
+ export type JudgePurpose = 'boss-input-classification' | 'player-output-adjudication' | 'captain-output-adjudication';
43
+ /**
44
+ * Traced runtime boundary used by the provided actors. The factory's runtime
45
+ * implements it; standalone helpers accept it optionally so verification can
46
+ * exercise composition/adjudication without a live runtime.
47
+ */
48
+ export interface RuntimeBoundaryCalls {
49
+ callPlayer(input: PlaybookPlayerInput, playerId: string, prompt: string, signal: AbortSignal): Promise<PlayerResult>;
50
+ callJudge(purpose: JudgePurpose, stateId: string | undefined, prompt: string, signal: AbortSignal): Promise<string>;
51
+ callCaptain?(input: PlaybookCaptainInput, prompt: string, signal: AbortSignal): Promise<CaptainResult>;
52
+ }
53
+ export interface ScheduledStatus {
54
+ message: string;
55
+ data?: JsonValue;
56
+ }
57
+ export interface XStateBossEventFieldSpec {
58
+ /** The judge supplies routing data; the runtime supplies exact Boss text. */
59
+ source: 'judge' | 'text';
60
+ /** Judge-authored fields are optional unless explicitly required. */
61
+ required?: boolean;
62
+ /** Optional closed set for a string-valued judge field. */
63
+ values?: readonly string[];
64
+ }
65
+ export interface XStateBossEventSpec {
66
+ type: string;
67
+ fields?: Readonly<Record<string, XStateBossEventFieldSpec>>;
68
+ }
69
+ export declare const BOSS_REPLY_ERRORS: {
70
+ readonly missingQuestion: "needsBossReply outcome missing 'question' field";
71
+ readonly unregisteredState: (stateId: string) => string;
72
+ };
73
+ export interface XStatePlaybookRuntimeSpec<TOptions> {
74
+ /** Diagnostic label used in internal invariant errors. Default 'playbook'. */
75
+ label?: string;
76
+ /** Validate and JSON-snapshot the caller's per-run options. */
77
+ snapshotOptions: (value: unknown) => TOptions;
78
+ /** Derive the FSM machine input from validated options. Default: identity. */
79
+ machineInput?: (options: TOptions, session: PlaybookSession) => unknown;
80
+ /**
81
+ * Deterministic textual entry event (slc/link.md §Boss-event mapping):
82
+ * where the ready or reconstructed terminal machine accepts exactly one
83
+ * ordinary textual entry event, send it without a judge call, carrying the
84
+ * exact Boss text in `textField`. Absent: every non-empty turn classifies.
85
+ */
86
+ entryEvent?: {
87
+ type: string;
88
+ textField: string;
89
+ };
90
+ /**
91
+ * Exact flat Boss-event contracts whose non-text fields the judge may
92
+ * select. `entryEvent` and scalar `BOSS_REPLY` contracts are supplied by
93
+ * the factory; linkers emit entries here for additional typed events such
94
+ * as `BOSS_INTERRUPT` when their erased payload cannot be recovered from
95
+ * the XState machine alone.
96
+ */
97
+ bossEvents?: readonly XStateBossEventSpec[];
98
+ /** Boss-input classifier override; default: generic parked-state classifier. */
99
+ classifyBossText?: (text: string, ports: PlaybookPorts, signal: AbortSignal, snapshotOrState: unknown, boundary?: RuntimeBoundaryCalls) => Promise<EventObject | undefined>;
100
+ /** Status line emitted after classification names an event. Default: none. */
101
+ classificationStatus?: (event: EventObject) => string | undefined;
102
+ /** Map a player-invoking state's input to the host player id. Default: lowercased player name. */
103
+ resolvePlayerId?: (input: PlaybookPlayerInput, options: TOptions) => string;
104
+ /** Compose the player prompt. Default: continuation blocks + `<field>` placeholder substitution. */
105
+ composePlayerPrompt?: (input: PlaybookPlayerInput) => string;
106
+ /** Compose the direct-Captain prompt. Default: continuation blocks + placeholder substitution with deterministic JSON rendering. */
107
+ composeCaptainPrompt?: (input: PlaybookCaptainInput) => string;
108
+ /** Linker-known exceptions to the default kebab-token → camel-field mapping. */
109
+ placeholderFields?: Readonly<Record<string, string>>;
110
+ /** Adjudicator prompt for delegated players. Default: generic guard menu. */
111
+ buildJudgePrompt?: (input: PlaybookPlayerInput, finalText: string) => string;
112
+ /** Required-payload-field extraction from a `result` description. Default: bilingual `Output shall include` clause scan. */
113
+ extractRequiredFields?: (description: string) => string[];
114
+ /** Required fields carried verbatim from the player's finalText instead of judge JSON. Default: none. */
115
+ verbatimPayloadFields?: ReadonlySet<string>;
116
+ /** States that may suspend for a Boss reply. Default: targets of the FSM's `awaitBossReply` BOSS_REPLY transitions. */
117
+ resumableStateIds?: ReadonlySet<string>;
118
+ /** Human status lines for a root transition. Default: entry lines with question/failure surfacing. */
119
+ statusesForState?: (state: PlaybookState, context: Record<string, unknown>, event: unknown) => readonly ScheduledStatus[];
120
+ /** Detached JSON-safe transition-event descriptor. Default: `type` + `transitionEventFields` strings + validated output + normalized error. */
121
+ normalizeTransitionEvent?: (event: unknown) => JsonValue | undefined;
122
+ /** String payload fields the default transition-event descriptor copies. */
123
+ transitionEventFields?: readonly string[];
124
+ /** Working directory for `script` actors. Default: the validated options' string `cwd`, else the process working directory. */
125
+ scriptCwd?: (options: TOptions) => string | undefined;
126
+ }
127
+ /** Strip a single Markdown code fence that wraps the whole string. */
128
+ export declare function stripCodeFence(text: string): string;
129
+ export declare function extractJsonValue(text: string, start: number, repair: boolean): string | undefined;
130
+ export declare function parseJudgeJson(raw: string): unknown;
131
+ export declare function normalizeErrorCompact(err: unknown): {
132
+ name: string;
133
+ message: string;
134
+ } | undefined;
135
+ export declare function normalizeErrorFull(err: unknown): {
136
+ name: string;
137
+ message: string;
138
+ stack?: string;
139
+ } | undefined;
140
+ /** Read the FSM context's single pending Boss question, when well-formed. */
141
+ export declare function pendingBossQuestionFromContext(context: Record<string, unknown>): PlaybookPendingBossQuestionContext | undefined;
142
+ /**
143
+ * Default player-prompt composer (slc/link.md §Player prompt composition).
144
+ * One callback-based pass substitutes each `<fieldName>` placeholder whose
145
+ * typed input field is a string; replacement text is literal, and
146
+ * placeholder-looking text inside a value is never re-substituted. The
147
+ * continuation preamble and Q/A blocks precede the domain body on resume.
148
+ */
149
+ export declare function defaultComposePlayerPrompt(input: PlaybookPlayerInput, placeholderFields?: Readonly<Record<string, string>>): string;
150
+ /**
151
+ * Default direct-Captain prompt composer (slc/link.md §Captain prompt
152
+ * composition). Placeholder substitution is presence-based: string fields
153
+ * substitute verbatim; JSON-safe arrays/objects render as deterministic JSON
154
+ * with lexicographically sorted keys at every depth.
155
+ */
156
+ export declare function defaultComposeCaptainPrompt(input: PlaybookCaptainInput, placeholderFields?: Readonly<Record<string, string>>): string;
157
+ /** Default player binding: each player to its lowercased name. */
158
+ export declare function defaultResolvePlayerId(input: PlaybookPlayerInput): string;
159
+ /**
160
+ * Default required-field extraction (slc/link.md §Captain adjudication).
161
+ * Limited to the description's `Output shall include` / `输出应包含` clause;
162
+ * recognizes both the bare backticked name and the annotated `name: <...>`
163
+ * form.
164
+ */
165
+ export declare function defaultExtractRequiredFields(description: string): string[];
166
+ /** Default delegated-player adjudicator prompt. */
167
+ export declare function defaultBuildJudgePrompt(input: PlaybookPlayerInput, finalText: string): string;
168
+ export interface PlayerAdjudicationSpec {
169
+ buildJudgePrompt?: (input: PlaybookPlayerInput, finalText: string) => string;
170
+ extractRequiredFields?: (description: string) => string[];
171
+ verbatimPayloadFields?: ReadonlySet<string>;
172
+ }
173
+ /**
174
+ * LLM-judge adjudicator for delegated players. Coerces the player's
175
+ * finalText into one of the state's declared guards, extracts every required
176
+ * payload field from the judge reply, and fails loudly (throws) on a missing
177
+ * JSON object, an undeclared guard, or a missing required field. Fields in
178
+ * `verbatimPayloadFields` carry `finalText.trim()` rather than round-tripping
179
+ * long-form prose through judge JSON.
180
+ */
181
+ export declare function adjudicatePlayerOutput(spec: PlayerAdjudicationSpec, input: PlaybookPlayerInput, finalText: string, ports: PlaybookPorts, signal: AbortSignal, boundary?: RuntimeBoundaryCalls): Promise<PlaybookActorOutput>;
182
+ export interface PlayerBridgeSpec {
183
+ resolvePlayerId: (input: PlaybookPlayerInput) => string;
184
+ composePlayerPrompt: (input: PlaybookPlayerInput) => string;
185
+ adjudication: PlayerAdjudicationSpec;
186
+ resumableStateIds: ReadonlySet<string>;
187
+ }
188
+ export declare function createPlayerBridge(spec: PlayerBridgeSpec, ports: PlaybookPorts, getActiveSignal?: () => AbortSignal | undefined, boundary?: RuntimeBoundaryCalls, onControlPlaneError?: (error: unknown) => void): PromiseActorLogic<PlaybookActorOutput, PlaybookPlayerInput>;
189
+ /** Targets of the FSM's `awaitBossReply` BOSS_REPLY transitions. */
190
+ export declare function resumableStateIdsFromMachine(machine: AnyStateMachine): ReadonlySet<string>;
191
+ /**
192
+ * Build a `PlaybookRuntimeFactory` that interprets the given FSM artifact
193
+ * under the slc/link.md contract. The factory provides every actor kind the
194
+ * machine declares — `player`, `script`, `captain`, and nested `playbook`
195
+ * (literal and dynamic) — and implements the full runtime lifecycle including
196
+ * the optional parked-session snapshot capability (DR-014).
197
+ *
198
+ * Scope: single-region root machines (each snapshot exposes exactly one
199
+ * playbook state id). Parallel-region FSMs keep their own linked runtimes.
200
+ */
201
+ export declare function createXStatePlaybookRuntime<TOptions>(machine: AnyStateMachine, spec: XStatePlaybookRuntimeSpec<TOptions>): PlaybookRuntimeFactory<TOptions>;