@sublang/playbook 8.0.0 → 10.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/docs/cli.md +66 -23
- package/docs/configuration.md +13 -8
- package/docs/embedding.md +45 -14
- package/package.json +7 -3
- package/reference/sdlc/captain.md +14 -10
- package/reference/sdlc/captain.playbook/captain.fsm.d.ts +33 -13
- package/reference/sdlc/captain.playbook/captain.fsm.js +80 -9
- package/reference/sdlc/captain.playbook/captain.fsm.ts +137 -18
- package/reference/sdlc/captain.playbook/captain.gears.md +10 -6
- package/reference/sdlc/captain.playbook/captain.playbook.d.ts +5 -1
- package/reference/sdlc/captain.playbook/captain.playbook.js +151 -10
- package/reference/sdlc/captain.playbook/captain.playbook.ts +200 -14
- package/reference/sdlc/code.md +0 -1
- package/reference/sdlc/code.playbook/bin/interactive-session.js +170 -17
- package/reference/sdlc/code.playbook/bin/launch-config.js +136 -4
- package/reference/sdlc/code.playbook/bin/playbook.js +81 -4
- package/reference/sdlc/code.playbook/bin/repository-effects.js +2930 -0
- package/reference/sdlc/code.playbook/bin/run.js +365 -63
- package/reference/sdlc/code.playbook/bin/session-store.js +2877 -209
- package/reference/sdlc/code.playbook/code.fsm.d.ts +11 -1
- package/reference/sdlc/code.playbook/code.fsm.js +85 -29
- package/reference/sdlc/code.playbook/code.fsm.ts +95 -33
- package/reference/sdlc/code.playbook/code.gears.md +0 -2
- package/reference/sdlc/code.playbook/code.playbook.d.ts +5 -2
- package/reference/sdlc/code.playbook/code.playbook.js +67 -4
- package/reference/sdlc/code.playbook/code.playbook.ts +87 -8
- package/reference/sdlc/code.playbook/code.registry.d.ts +10 -3
- package/reference/sdlc/code.playbook/code.registry.js +10 -3
- package/reference/sdlc/code.playbook/code.registry.ts +23 -5
- package/reference/sdlc/code.playbook/playbook-captain.d.ts +99 -7
- package/reference/sdlc/code.playbook/playbook-captain.js +1894 -82
- package/reference/sdlc/code.playbook/playbook-captain.ts +2809 -109
- package/reference/sdlc/decide.md +0 -1
- package/reference/sdlc/decide.playbook/decide.fsm.d.ts +8 -1
- package/reference/sdlc/decide.playbook/decide.fsm.js +80 -29
- package/reference/sdlc/decide.playbook/decide.fsm.ts +89 -31
- package/reference/sdlc/decide.playbook/decide.gears.md +0 -1
- package/reference/sdlc/decide.playbook/decide.playbook.d.ts +15 -5
- package/reference/sdlc/decide.playbook/decide.playbook.js +1994 -191
- package/reference/sdlc/decide.playbook/decide.playbook.ts +3209 -404
- package/reference/sdlc/decide.playbook/decide.registry.d.ts +7 -3
- package/reference/sdlc/decide.playbook/decide.registry.js +10 -3
- package/reference/sdlc/decide.playbook/decide.registry.ts +20 -5
- package/reference/sdlc/review.playbook/review.fsm.d.ts +7 -0
- package/reference/sdlc/review.playbook/review.fsm.js +133 -12
- package/reference/sdlc/review.playbook/review.fsm.ts +140 -12
- package/reference/sdlc/review.playbook/review.playbook.d.ts +5 -2
- package/reference/sdlc/review.playbook/review.playbook.js +78 -4
- package/reference/sdlc/review.playbook/review.playbook.ts +95 -8
- package/reference/sdlc/review.playbook/review.registry.d.ts +10 -3
- package/reference/sdlc/review.playbook/review.registry.js +10 -3
- package/reference/sdlc/review.playbook/review.registry.ts +23 -5
- package/slc/gears2fsm.md +25 -7
- package/slc/link.md +727 -82
- package/src/accepted-outcome.d.ts +18 -0
- package/src/accepted-outcome.js +94 -0
- package/src/accepted-outcome.ts +140 -0
- package/src/runtime.d.ts +165 -3
- package/src/runtime.ts +214 -2
- package/src/xstate-playbook-runtime.d.ts +162 -13
- package/src/xstate-playbook-runtime.js +3344 -564
- package/src/xstate-playbook-runtime.ts +4873 -637
- package/src/xstate-runtime.d.ts +76 -8
- package/src/xstate-runtime.js +1001 -64
- package/src/xstate-runtime.ts +1640 -91
package/src/runtime.ts
CHANGED
|
@@ -83,10 +83,13 @@ export interface PlaybookPendingCall {
|
|
|
83
83
|
// DR-031 §5: complete durable identity for one nested call whose start
|
|
84
84
|
// boundary has already been published and whose child remains suspended.
|
|
85
85
|
// `turnId` is absent when the call was opened outside a Boss-turn boundary.
|
|
86
|
+
// A schema-3 runtime adds the effect-ledger prefix captured before the causal
|
|
87
|
+
// public boundary; null records that the prefix could not be observed.
|
|
86
88
|
export interface PlaybookSuspendedCall extends PlaybookPendingCall {
|
|
87
89
|
stateId: string;
|
|
88
90
|
text: string;
|
|
89
91
|
turnId?: number;
|
|
92
|
+
effectBoundaryPrefixSequence?: number | null;
|
|
90
93
|
}
|
|
91
94
|
|
|
92
95
|
export interface PlaybookCallRequest {
|
|
@@ -124,6 +127,7 @@ export type PlaybookCallStart =
|
|
|
124
127
|
|
|
125
128
|
export type PlaybookRunResult =
|
|
126
129
|
| { outcome: 'quiescent' | 'no-action'; state: PlaybookState }
|
|
130
|
+
| { outcome: 'unresolved-effect'; state: PlaybookState }
|
|
127
131
|
| {
|
|
128
132
|
outcome: 'failed' | 'aborted';
|
|
129
133
|
state: PlaybookState;
|
|
@@ -132,6 +136,7 @@ export type PlaybookRunResult =
|
|
|
132
136
|
| {
|
|
133
137
|
outcome: 'terminal';
|
|
134
138
|
state: PlaybookState;
|
|
139
|
+
stateDescription?: string;
|
|
135
140
|
output?: JsonValue;
|
|
136
141
|
}
|
|
137
142
|
| {
|
|
@@ -173,6 +178,16 @@ export interface PlaybookSession {
|
|
|
173
178
|
ports: PlaybookPorts;
|
|
174
179
|
}
|
|
175
180
|
|
|
181
|
+
// DR-038 §5: the source identities and, for a suspended nested call, the
|
|
182
|
+
// fresh target child identity that let adoption start one explicit target
|
|
183
|
+
// trace lineage without carrying source-session counters or child UUIDs
|
|
184
|
+
// forward.
|
|
185
|
+
export interface PlaybookAdoptionContext {
|
|
186
|
+
readonly sourceSessionId: string;
|
|
187
|
+
readonly sourceGenerationId: string;
|
|
188
|
+
readonly targetChildSessionId?: string;
|
|
189
|
+
}
|
|
190
|
+
|
|
176
191
|
export type PlaybookTraceType =
|
|
177
192
|
| 'session.started'
|
|
178
193
|
| 'boss.input.received'
|
|
@@ -187,12 +202,13 @@ export type PlaybookTraceType =
|
|
|
187
202
|
| 'apply.started'
|
|
188
203
|
| 'apply.finished'
|
|
189
204
|
| 'fsm.transition'
|
|
205
|
+
| 'outcome.accepted'
|
|
190
206
|
| 'status.emitted'
|
|
191
207
|
| 'boss.input.settled'
|
|
192
208
|
| 'session.disposed';
|
|
193
209
|
|
|
194
210
|
export interface PlaybookTraceEvent {
|
|
195
|
-
schemaVersion:
|
|
211
|
+
schemaVersion: 4;
|
|
196
212
|
sessionId: string;
|
|
197
213
|
playbookId: string;
|
|
198
214
|
rootSessionId: string;
|
|
@@ -214,12 +230,164 @@ export interface PlaybookPendingBossQuestion {
|
|
|
214
230
|
sourceItem?: string;
|
|
215
231
|
}
|
|
216
232
|
|
|
233
|
+
/** One repository disposition declared by a governed outcome arm (DR-040). */
|
|
234
|
+
export type PlaybookRepositoryDisposition =
|
|
235
|
+
| 'unchanged'
|
|
236
|
+
| 'one-descendant-commit'
|
|
237
|
+
| 'deferred';
|
|
238
|
+
|
|
239
|
+
/** A detached Git-visible repository observation owned by the effect ledger. */
|
|
240
|
+
export interface PlaybookRepositoryObservation {
|
|
241
|
+
readonly worktree: string;
|
|
242
|
+
readonly gitDir: string;
|
|
243
|
+
readonly head: string;
|
|
244
|
+
readonly projection: Readonly<Record<string, JsonValue>>;
|
|
245
|
+
readonly projectionDigest: string;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/** The fail-closed classification of one complete physical or logical receipt. */
|
|
249
|
+
export interface PlaybookRepositoryReceipt {
|
|
250
|
+
readonly classification:
|
|
251
|
+
| 'unchanged'
|
|
252
|
+
| 'one-descendant-commit'
|
|
253
|
+
| 'multiple-commits'
|
|
254
|
+
| 'rewritten-or-non-descendant'
|
|
255
|
+
| 'worktree-only-change'
|
|
256
|
+
| 'concurrent-or-foreign-change'
|
|
257
|
+
| 'observation-ambiguous';
|
|
258
|
+
readonly baseline: PlaybookRepositoryObservation;
|
|
259
|
+
readonly after?: PlaybookRepositoryObservation;
|
|
260
|
+
readonly commitOid?: string;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/** One durably ordered physical governed-player boundary (DR-040). */
|
|
264
|
+
export interface PlaybookEffectBoundary {
|
|
265
|
+
readonly sequence: number;
|
|
266
|
+
readonly boundaryId: string;
|
|
267
|
+
readonly attemptId: string;
|
|
268
|
+
readonly attemptNumber: number;
|
|
269
|
+
readonly playbookId: string;
|
|
270
|
+
readonly runtimeSessionId: string;
|
|
271
|
+
readonly turnId: number;
|
|
272
|
+
readonly callId: string;
|
|
273
|
+
readonly roleId: string;
|
|
274
|
+
readonly sourceStateId: string;
|
|
275
|
+
readonly sourceOutcomeSchema: JsonValue;
|
|
276
|
+
readonly dispositions: readonly PlaybookRepositoryDisposition[];
|
|
277
|
+
readonly canonicalWorktree: {
|
|
278
|
+
readonly worktree: string;
|
|
279
|
+
readonly gitDir: string;
|
|
280
|
+
};
|
|
281
|
+
readonly baseline: PlaybookRepositoryObservation;
|
|
282
|
+
readonly after?: PlaybookRepositoryObservation;
|
|
283
|
+
readonly physicalReceipt?: PlaybookRepositoryReceipt;
|
|
284
|
+
readonly finalText?: string;
|
|
285
|
+
readonly semanticCandidate?: JsonValue;
|
|
286
|
+
readonly initialSemanticCandidate?: JsonValue;
|
|
287
|
+
readonly correctionBudget: { readonly limit: 1; readonly spent: boolean };
|
|
288
|
+
readonly cohortId?: string;
|
|
289
|
+
readonly logicalOperationId?: string;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/** One physical boundary before the host assigns attempt and sequence data. */
|
|
293
|
+
export type PlaybookEffectBoundaryStart = Omit<
|
|
294
|
+
PlaybookEffectBoundary,
|
|
295
|
+
| 'sequence'
|
|
296
|
+
| 'attemptId'
|
|
297
|
+
| 'attemptNumber'
|
|
298
|
+
| 'after'
|
|
299
|
+
| 'physicalReceipt'
|
|
300
|
+
| 'finalText'
|
|
301
|
+
| 'semanticCandidate'
|
|
302
|
+
| 'initialSemanticCandidate'
|
|
303
|
+
>;
|
|
304
|
+
|
|
305
|
+
/** One deferred logical operation spanning its ordered physical boundaries. */
|
|
306
|
+
export interface PlaybookEffectLogicalOperation {
|
|
307
|
+
readonly sequence: number;
|
|
308
|
+
readonly operationId: string;
|
|
309
|
+
readonly playbookId: string;
|
|
310
|
+
readonly runtimeSessionId: string;
|
|
311
|
+
readonly boundaryIds: readonly string[];
|
|
312
|
+
readonly originalBaseline: PlaybookRepositoryObservation;
|
|
313
|
+
readonly checkpoint?: PlaybookRepositoryObservation;
|
|
314
|
+
readonly pendingQuestion?: PlaybookPendingBossQuestion;
|
|
315
|
+
readonly playerContinuation?: JsonValue;
|
|
316
|
+
readonly checkpointRestorationEligible: boolean;
|
|
317
|
+
readonly logicalReceipt?: PlaybookRepositoryReceipt;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/** Complete detached mirror of one host-owned reconciliation ledger. */
|
|
321
|
+
export interface PlaybookEffectLedger {
|
|
322
|
+
readonly schemaVersion: 1;
|
|
323
|
+
readonly revision: number;
|
|
324
|
+
readonly boundaries: readonly PlaybookEffectBoundary[];
|
|
325
|
+
readonly logicalOperations: readonly PlaybookEffectLogicalOperation[];
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/** One mutation accepted by the host-owned effect-ledger write-ahead boundary. */
|
|
329
|
+
export type PlaybookEffectLedgerCommand =
|
|
330
|
+
| {
|
|
331
|
+
readonly kind: 'start-boundaries';
|
|
332
|
+
readonly boundaries: readonly [
|
|
333
|
+
PlaybookEffectBoundaryStart,
|
|
334
|
+
...PlaybookEffectBoundaryStart[],
|
|
335
|
+
];
|
|
336
|
+
}
|
|
337
|
+
| {
|
|
338
|
+
readonly kind: 'replace-boundaries';
|
|
339
|
+
readonly replacements: readonly [
|
|
340
|
+
{
|
|
341
|
+
readonly expected: PlaybookEffectBoundary;
|
|
342
|
+
readonly next: PlaybookEffectBoundary;
|
|
343
|
+
},
|
|
344
|
+
...{
|
|
345
|
+
readonly expected: PlaybookEffectBoundary;
|
|
346
|
+
readonly next: PlaybookEffectBoundary;
|
|
347
|
+
}[],
|
|
348
|
+
];
|
|
349
|
+
}
|
|
350
|
+
| {
|
|
351
|
+
readonly kind: 'append-logical-operations';
|
|
352
|
+
readonly operations: readonly [
|
|
353
|
+
Omit<PlaybookEffectLogicalOperation, 'sequence'>,
|
|
354
|
+
...Omit<PlaybookEffectLogicalOperation, 'sequence'>[],
|
|
355
|
+
];
|
|
356
|
+
}
|
|
357
|
+
| {
|
|
358
|
+
readonly kind: 'replace-logical-operations';
|
|
359
|
+
readonly replacements: readonly [
|
|
360
|
+
{
|
|
361
|
+
readonly expected: PlaybookEffectLogicalOperation;
|
|
362
|
+
readonly next: PlaybookEffectLogicalOperation;
|
|
363
|
+
},
|
|
364
|
+
...{
|
|
365
|
+
readonly expected: PlaybookEffectLogicalOperation;
|
|
366
|
+
readonly next: PlaybookEffectLogicalOperation;
|
|
367
|
+
}[],
|
|
368
|
+
];
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
/** A nonempty command batch persisted as one ledger revision. */
|
|
372
|
+
export type PlaybookEffectLedgerCommandBatch = readonly [
|
|
373
|
+
PlaybookEffectLedgerCommand,
|
|
374
|
+
...PlaybookEffectLedgerCommand[],
|
|
375
|
+
];
|
|
376
|
+
|
|
377
|
+
/** Live current-host seam for atomic effect-ledger observation and mutation. */
|
|
378
|
+
export interface PlaybookEffectLedgerCapability {
|
|
379
|
+
snapshot(): PlaybookEffectLedger;
|
|
380
|
+
writeAhead(
|
|
381
|
+
commands: PlaybookEffectLedgerCommandBatch,
|
|
382
|
+
): Promise<PlaybookEffectLedger>;
|
|
383
|
+
}
|
|
384
|
+
|
|
217
385
|
// DR-014 §1 / DR-031 §5 / DR-032: JSON-safe capture of a parked or nested-call
|
|
218
386
|
// suspended session. `machine` is the opaque XState persisted snapshot;
|
|
219
387
|
// pending Boss questions and a suspended call are first-class so a
|
|
220
388
|
// host never has to reconstruct durable ownership from presentation records.
|
|
221
389
|
export interface PlaybookRuntimeSnapshot {
|
|
222
|
-
schemaVersion:
|
|
390
|
+
schemaVersion: 4;
|
|
223
391
|
playbookId: string;
|
|
224
392
|
machine: JsonValue;
|
|
225
393
|
roleResumeTokens: { readonly [roleId: string]: string };
|
|
@@ -233,6 +401,21 @@ export interface PlaybookRuntimeSnapshot {
|
|
|
233
401
|
};
|
|
234
402
|
state: PlaybookState;
|
|
235
403
|
pendingBossQuestions: readonly PlaybookPendingBossQuestion[];
|
|
404
|
+
effectLedger: PlaybookEffectLedger;
|
|
405
|
+
/** Original runtime identity retained across schema-3 adoption lineage. */
|
|
406
|
+
retainedEffectSourceSessionId?: string;
|
|
407
|
+
/**
|
|
408
|
+
* Unsafe retained-adoption checkpoint. The marker remains durable until
|
|
409
|
+
* authoritative reconciliation proves its complete suffix replay-safe.
|
|
410
|
+
*/
|
|
411
|
+
retainedEffectReconciliation?: {
|
|
412
|
+
readonly sourceSessionId: string;
|
|
413
|
+
readonly checkpoint: PlaybookEffectLedger;
|
|
414
|
+
};
|
|
415
|
+
failedEffectAttempt?: {
|
|
416
|
+
readonly boundaryPrefix: number;
|
|
417
|
+
readonly attemptId: string | null;
|
|
418
|
+
};
|
|
236
419
|
suspendedCall?: PlaybookSuspendedCall;
|
|
237
420
|
}
|
|
238
421
|
|
|
@@ -268,6 +451,15 @@ export type PlaybookControlReceipt =
|
|
|
268
451
|
| { disposition: 'executed'; run: PlaybookRunResult }
|
|
269
452
|
| { disposition: 'failed'; error: NormalizedError };
|
|
270
453
|
|
|
454
|
+
// DR-038 §2: link-authored metadata the Captain uses to decide whether a
|
|
455
|
+
// quiescent generation is eligible for retention and whether a root terminal
|
|
456
|
+
// outcome preserves its pre-terminal generation. Presence is classification
|
|
457
|
+
// data, independent from the optional adoption operation; an explicitly empty
|
|
458
|
+
// final-state list is meaningful.
|
|
459
|
+
export interface PlaybookRetainedGenerationMetadata {
|
|
460
|
+
readonly unfinishedFinalStateIds: readonly string[];
|
|
461
|
+
}
|
|
462
|
+
|
|
271
463
|
export interface PlaybookRuntime {
|
|
272
464
|
init(session: PlaybookSession): Promise<void>;
|
|
273
465
|
// DR-014 §1 optional durable-session capability: a runtime implements
|
|
@@ -280,6 +472,16 @@ export interface PlaybookRuntime {
|
|
|
280
472
|
session: PlaybookSession,
|
|
281
473
|
snapshot: PlaybookRuntimeSnapshot,
|
|
282
474
|
): Promise<void>;
|
|
475
|
+
// DR-038 §1 optional generation-adoption capability: a distinct
|
|
476
|
+
// initialization path that rehydrates a retained snapshot under a fresh
|
|
477
|
+
// engagement identity. Presence is feature-detected independently from
|
|
478
|
+
// retained-generation classification metadata.
|
|
479
|
+
adopt?(
|
|
480
|
+
session: PlaybookSession,
|
|
481
|
+
snapshot: PlaybookRuntimeSnapshot,
|
|
482
|
+
context: PlaybookAdoptionContext,
|
|
483
|
+
): Promise<void>;
|
|
484
|
+
readonly retainedGenerationMetadata?: PlaybookRetainedGenerationMetadata;
|
|
283
485
|
// DR-029 optional control-surface capability: a runtime implements
|
|
284
486
|
// both members or neither. `describe` is side-effect free and valid at
|
|
285
487
|
// parked quiescence outside an active boundary; `apply` revalidates the
|
|
@@ -288,6 +490,16 @@ export interface PlaybookRuntime {
|
|
|
288
490
|
// runtime lacking the pair advertises no actions; plain text delivery is
|
|
289
491
|
// the only verb against it.
|
|
290
492
|
describe?(): PlaybookControlView;
|
|
493
|
+
/**
|
|
494
|
+
* Host-only identities of the durable envelopes that still require
|
|
495
|
+
* unresolved-effect settlement. The host owns their bounded projection
|
|
496
|
+
* from its authoritative effect ledger; no repository evidence enters a
|
|
497
|
+
* runtime-owned run result.
|
|
498
|
+
*/
|
|
499
|
+
unresolvedEffectEnvelopes?(): readonly (
|
|
500
|
+
| { readonly kind: 'boundary'; readonly boundaryId: string }
|
|
501
|
+
| { readonly kind: 'logical-operation'; readonly operationId: string }
|
|
502
|
+
)[];
|
|
291
503
|
apply?(input: {
|
|
292
504
|
actionId: string;
|
|
293
505
|
key: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AnyStateMachine, EventObject, PromiseActorLogic } from 'xstate';
|
|
2
|
-
import type { CaptainResult, JsonValue, PlaybookPorts, PlaybookRuntimeFactory, PlaybookSession, PlaybookState, PlayerResult } from './runtime.js';
|
|
2
|
+
import type { CaptainResult, JsonValue, PlaybookEffectBoundary, PlaybookEffectBoundaryStart, PlaybookEffectLedger, PlaybookEffectLedgerCapability, PlaybookPendingBossQuestion, PlaybookPorts, PlaybookRepositoryReceipt, PlaybookRuntimeFactory, PlaybookSession, PlaybookState, PlayerResult } from './runtime.js';
|
|
3
3
|
export interface PlaybookPendingBossQuestionContext {
|
|
4
4
|
questionId: string;
|
|
5
5
|
resumeStateId: string;
|
|
@@ -52,9 +52,23 @@ export type JudgePurpose = 'boss-input-classification' | 'player-output-adjudica
|
|
|
52
52
|
*/
|
|
53
53
|
export interface RuntimeBoundaryCalls {
|
|
54
54
|
callPlayer(input: PlaybookPlayerInput, roleId: string, prompt: string, signal: AbortSignal): Promise<PlayerResult>;
|
|
55
|
+
/**
|
|
56
|
+
* Return the host-acknowledged adjudication performed while a governed
|
|
57
|
+
* repository claim was still held. The value is consumable once.
|
|
58
|
+
*/
|
|
59
|
+
takeGovernedPlayerOutput?(result: PlayerResult): GovernedPlayerSettlement | undefined;
|
|
60
|
+
recordGovernedPlayerOutput?(result: PlayerResult, output: PlaybookActorOutput): void;
|
|
55
61
|
callJudge(purpose: JudgePurpose, stateId: string | undefined, prompt: string, signal: AbortSignal): Promise<string>;
|
|
56
62
|
callCaptain?(input: PlaybookCaptainInput, prompt: string, signal: AbortSignal, callOptions?: XStateCaptainCallOptions): Promise<CaptainResult>;
|
|
57
63
|
}
|
|
64
|
+
/** Host-acknowledged outcome of one governed player reconciliation. */
|
|
65
|
+
type GovernedPlayerSettlement = {
|
|
66
|
+
readonly status: 'resolved';
|
|
67
|
+
readonly output: PlaybookActorOutput;
|
|
68
|
+
} | {
|
|
69
|
+
readonly status: 'unresolved';
|
|
70
|
+
readonly error: unknown;
|
|
71
|
+
};
|
|
58
72
|
/**
|
|
59
73
|
* Presentation selection for one traced direct-Captain call
|
|
60
74
|
* (slc/link.md §Captain adjudication). `'visible'` (the default) is the
|
|
@@ -95,6 +109,87 @@ export declare const BOSS_REPLY_ERRORS: {
|
|
|
95
109
|
readonly missingQuestion: "needsBossReply outcome missing 'question' field";
|
|
96
110
|
readonly unregisteredState: (stateId: string) => string;
|
|
97
111
|
};
|
|
112
|
+
interface XStateRepositoryOperationSettlement<T> {
|
|
113
|
+
readonly status: 'fulfilled';
|
|
114
|
+
readonly value: T;
|
|
115
|
+
}
|
|
116
|
+
interface XStateRepositoryOperationRejection {
|
|
117
|
+
readonly status: 'rejected';
|
|
118
|
+
readonly reason: unknown;
|
|
119
|
+
}
|
|
120
|
+
interface XStateRepositoryExclusiveCompletion<T> {
|
|
121
|
+
readonly boundary: PlaybookEffectBoundary;
|
|
122
|
+
readonly operation: XStateRepositoryOperationSettlement<T> | XStateRepositoryOperationRejection;
|
|
123
|
+
readonly receipt: PlaybookRepositoryReceipt;
|
|
124
|
+
/** Physical receipt for an ordinary call; cumulative receipt for a chain. */
|
|
125
|
+
readonly outcomeReceipt: PlaybookRepositoryReceipt;
|
|
126
|
+
}
|
|
127
|
+
interface XStateDeferredBinding {
|
|
128
|
+
readonly operationId: string;
|
|
129
|
+
readonly pendingQuestion: PlaybookPendingBossQuestion;
|
|
130
|
+
readonly playerContinuation: JsonValue;
|
|
131
|
+
}
|
|
132
|
+
interface XStateRepositoryCompletionEvidence {
|
|
133
|
+
readonly finalText?: string;
|
|
134
|
+
readonly semanticCandidate?: JsonValue;
|
|
135
|
+
readonly deferred?: XStateDeferredBinding;
|
|
136
|
+
readonly unresolved?: true;
|
|
137
|
+
}
|
|
138
|
+
interface XStateRepositoryExclusiveResult<T> {
|
|
139
|
+
readonly operation: XStateRepositoryOperationSettlement<T> | XStateRepositoryOperationRejection;
|
|
140
|
+
readonly receipt: PlaybookRepositoryReceipt;
|
|
141
|
+
readonly effectLedger: PlaybookEffectLedger;
|
|
142
|
+
readonly deferredStatus?: 'bound' | 'unresolved';
|
|
143
|
+
}
|
|
144
|
+
interface XStateRepositoryDeferredContinuationResult<T> {
|
|
145
|
+
readonly status: 'continued';
|
|
146
|
+
readonly operation: XStateRepositoryOperationSettlement<T> | XStateRepositoryOperationRejection;
|
|
147
|
+
readonly receipt: PlaybookRepositoryReceipt;
|
|
148
|
+
readonly logicalReceipt?: PlaybookRepositoryReceipt;
|
|
149
|
+
readonly effectLedger: PlaybookEffectLedger;
|
|
150
|
+
readonly deferredStatus?: 'bound' | 'unresolved';
|
|
151
|
+
}
|
|
152
|
+
interface XStateRepositoryDeferredCheckpointMismatch {
|
|
153
|
+
readonly status: 'checkpoint-mismatch' | 'ineligible';
|
|
154
|
+
readonly effectLedger: PlaybookEffectLedger;
|
|
155
|
+
}
|
|
156
|
+
interface XStateRepositoryDeferredParked {
|
|
157
|
+
readonly status: 'parked';
|
|
158
|
+
readonly effectLedger: PlaybookEffectLedger;
|
|
159
|
+
}
|
|
160
|
+
interface XStateRepositoryDeferredRestoreResult {
|
|
161
|
+
readonly status: 'restored' | 'checkpoint-mismatch' | 'ineligible';
|
|
162
|
+
readonly effectLedger: PlaybookEffectLedger;
|
|
163
|
+
}
|
|
164
|
+
type XStateEffectBoundarySeed = Omit<PlaybookEffectBoundaryStart, 'playbookId' | 'canonicalWorktree' | 'baseline' | 'cohortId'>;
|
|
165
|
+
export interface XStateRepositoryCapability {
|
|
166
|
+
runExclusive<T>(options: {
|
|
167
|
+
readonly signal: AbortSignal;
|
|
168
|
+
readonly effectBoundary: XStateEffectBoundarySeed;
|
|
169
|
+
readonly operation: (context: {
|
|
170
|
+
readonly baseline: PlaybookRepositoryReceipt['baseline'];
|
|
171
|
+
readonly identity: unknown;
|
|
172
|
+
}) => Promise<T>;
|
|
173
|
+
readonly completeEffectBoundary: (completion: XStateRepositoryExclusiveCompletion<T>) => XStateRepositoryCompletionEvidence | Promise<XStateRepositoryCompletionEvidence>;
|
|
174
|
+
}): Promise<XStateRepositoryExclusiveResult<T>>;
|
|
175
|
+
runDeferred<T>(options: {
|
|
176
|
+
readonly mode: 'continue';
|
|
177
|
+
readonly signal: AbortSignal;
|
|
178
|
+
readonly operationId: string;
|
|
179
|
+
readonly effectBoundary: XStateEffectBoundarySeed;
|
|
180
|
+
readonly operation: (context: {
|
|
181
|
+
readonly baseline: PlaybookRepositoryReceipt['baseline'];
|
|
182
|
+
readonly identity: unknown;
|
|
183
|
+
readonly playerContinuation: JsonValue;
|
|
184
|
+
}) => Promise<T>;
|
|
185
|
+
readonly completeEffectBoundary: (completion: XStateRepositoryExclusiveCompletion<T>) => XStateRepositoryCompletionEvidence | Promise<XStateRepositoryCompletionEvidence>;
|
|
186
|
+
}): Promise<XStateRepositoryDeferredContinuationResult<T> | XStateRepositoryDeferredCheckpointMismatch>;
|
|
187
|
+
runDeferred(options: {
|
|
188
|
+
readonly mode: 'park' | 'restore';
|
|
189
|
+
readonly signal: AbortSignal;
|
|
190
|
+
readonly operationId: string;
|
|
191
|
+
}): Promise<XStateRepositoryDeferredParked | XStateRepositoryDeferredRestoreResult>;
|
|
192
|
+
}
|
|
98
193
|
/** The runtime ABI this engine implements (DR-022). */
|
|
99
194
|
export declare const RUNTIME_ABI = 1;
|
|
100
195
|
/** The linked-artifact schema versions this engine accepts (DR-022). */
|
|
@@ -106,6 +201,43 @@ export interface XStatePlaybookRuntimeCompat {
|
|
|
106
201
|
/** The engine ABI the artifact was linked against. */
|
|
107
202
|
runtimeAbi: number;
|
|
108
203
|
}
|
|
204
|
+
/** Authority for one schema-3 delegated-player outcome payload field. */
|
|
205
|
+
export type XStateOutcomeFieldAuthority = 'presentation' | 'semantic' | 'effect' | 'runtime';
|
|
206
|
+
/** Repository disposition required by one schema-3 outcome arm. */
|
|
207
|
+
export type XStateRepositoryDisposition = 'unchanged' | 'one-descendant-commit' | 'deferred';
|
|
208
|
+
/** Closed authority and repository contract for one governed outcome. */
|
|
209
|
+
export interface XStateGovernedOutcomeSpec {
|
|
210
|
+
readonly fields: Readonly<Record<string, XStateOutcomeFieldAuthority>>;
|
|
211
|
+
readonly repositoryDisposition: XStateRepositoryDisposition;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Schema-3 authority metadata, keyed first by player state and then by its
|
|
215
|
+
* declared outcome. A roleless artifact supplies an explicitly empty
|
|
216
|
+
* `governedPlayerStates` object.
|
|
217
|
+
*/
|
|
218
|
+
export interface XStateOutcomeAuthoritySpec {
|
|
219
|
+
readonly governedPlayerStates: Readonly<Record<string, Readonly<Record<string, XStateGovernedOutcomeSpec>>>>;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Schema-3 factory input composed by a registry from persisted configured
|
|
223
|
+
* options and live current-host capabilities. The engine snapshots only the
|
|
224
|
+
* first member and never places the second in machine input or persistence.
|
|
225
|
+
*/
|
|
226
|
+
export interface XStatePlaybookRuntimeConstruction<ConfiguredOptions, HostCapabilities extends object> {
|
|
227
|
+
readonly configuredOptions: ConfiguredOptions;
|
|
228
|
+
readonly hostCapabilities: HostCapabilities & {
|
|
229
|
+
readonly repository: XStateRepositoryCapability;
|
|
230
|
+
readonly effectLedger: PlaybookEffectLedgerCapability;
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
export type XStatePlaybookRuntimeFactoryOptions<ConfiguredOptions, HostCapabilities extends object> = XStatePlaybookRuntimeConstruction<ConfiguredOptions, HostCapabilities>;
|
|
234
|
+
/** Shared XState factory with its captured, validated artifact compatibility. */
|
|
235
|
+
export type XStatePlaybookRuntimeFactory<Options = unknown, ArtifactSchema extends 3 = 3> = PlaybookRuntimeFactory<Options> & {
|
|
236
|
+
readonly compat: Readonly<{
|
|
237
|
+
readonly artifactSchema: ArtifactSchema;
|
|
238
|
+
readonly runtimeAbi: typeof RUNTIME_ABI;
|
|
239
|
+
}>;
|
|
240
|
+
};
|
|
109
241
|
/**
|
|
110
242
|
* One direct-Captain actor invocation handed to a spec's `captainStrategy`
|
|
111
243
|
* (slc/link.md §Captain adjudication, controller form). The engine owns
|
|
@@ -146,15 +278,9 @@ export interface XStateCaptainStrategyRun<TOptions> {
|
|
|
146
278
|
recoverableFailure<E extends Error>(error: E): E;
|
|
147
279
|
}
|
|
148
280
|
export type XStateCaptainStrategy<TOptions> = (run: XStateCaptainStrategyRun<TOptions>) => Promise<PlaybookActorOutput>;
|
|
149
|
-
|
|
281
|
+
interface XStatePlaybookRuntimeSpecBase<TOptions> {
|
|
150
282
|
/** Diagnostic label used in internal invariant errors. Default 'playbook'. */
|
|
151
283
|
label?: string;
|
|
152
|
-
/**
|
|
153
|
-
* Link-time compatibility declaration checked at construction against the
|
|
154
|
-
* loaded engine's self-report (DR-022). Absent declarations reject because
|
|
155
|
-
* their overloaded player metadata has no safe local-role interpretation.
|
|
156
|
-
*/
|
|
157
|
-
compat?: XStatePlaybookRuntimeCompat;
|
|
158
284
|
/** Validate and JSON-snapshot the caller's per-run options. */
|
|
159
285
|
snapshotOptions: (value: unknown) => TOptions;
|
|
160
286
|
/** Derive the FSM machine input from validated options. Default: identity. */
|
|
@@ -168,6 +294,15 @@ export interface XStatePlaybookRuntimeSpec<TOptions> {
|
|
|
168
294
|
entryEvent?: {
|
|
169
295
|
type: string;
|
|
170
296
|
textField: string;
|
|
297
|
+
/**
|
|
298
|
+
* DR-034: the FSM context member this machine's entry action copies the
|
|
299
|
+
* exact Boss text into. Where it is named, the failure-state retry
|
|
300
|
+
* builds its payload from that member of the live snapshot instead of
|
|
301
|
+
* from the process-local recorded event, so the action derives the same
|
|
302
|
+
* before and after `restore`. Absent: the recorded event stays the
|
|
303
|
+
* source and the action lives only as long as the process.
|
|
304
|
+
*/
|
|
305
|
+
contextField?: string;
|
|
171
306
|
};
|
|
172
307
|
/**
|
|
173
308
|
* Exact flat Boss-event contracts whose non-text fields the judge may
|
|
@@ -217,6 +352,8 @@ export interface XStatePlaybookRuntimeSpec<TOptions> {
|
|
|
217
352
|
* surfaced first-class by the view and shall not be named here.
|
|
218
353
|
*/
|
|
219
354
|
controlContextFields?: readonly string[];
|
|
355
|
+
/** Root final states whose terminal outcome leaves unfinished work. Default: none. */
|
|
356
|
+
unfinishedFinalStateIds?: ReadonlySet<string>;
|
|
220
357
|
/** States that may suspend for a Boss reply. Default: targets of the FSM's `awaitBossReply` BOSS_REPLY transitions. */
|
|
221
358
|
resumableStateIds?: ReadonlySet<string>;
|
|
222
359
|
/** Human status lines for a root transition. Default: guard, declared-player, question, and failure lines. */
|
|
@@ -228,6 +365,14 @@ export interface XStatePlaybookRuntimeSpec<TOptions> {
|
|
|
228
365
|
/** Working directory for `script` actors. Default: the validated options' string `cwd`, else the process working directory. */
|
|
229
366
|
scriptCwd?: (options: TOptions) => string | undefined;
|
|
230
367
|
}
|
|
368
|
+
export interface XStatePlaybookRuntimeSpec<TOptions> extends XStatePlaybookRuntimeSpecBase<TOptions> {
|
|
369
|
+
compat: XStatePlaybookRuntimeCompat & {
|
|
370
|
+
artifactSchema: 3;
|
|
371
|
+
};
|
|
372
|
+
outcomeAuthority: XStateOutcomeAuthoritySpec;
|
|
373
|
+
}
|
|
374
|
+
/** Schema-3 shared-engine spec with required exact outcome authority metadata. */
|
|
375
|
+
export type XStatePlaybookRuntimeSpecV3<TOptions> = XStatePlaybookRuntimeSpec<TOptions>;
|
|
231
376
|
/** Strip a single Markdown code fence that wraps the whole string. */
|
|
232
377
|
export declare function stripCodeFence(text: string): string;
|
|
233
378
|
export declare function extractJsonValue(text: string, start: number, repair: boolean): string | undefined;
|
|
@@ -283,9 +428,11 @@ export interface PlayerAdjudicationSpec {
|
|
|
283
428
|
export declare function adjudicatePlayerOutput(spec: PlayerAdjudicationSpec, input: PlaybookPlayerInput, finalText: string, ports: PlaybookPorts, signal: AbortSignal, boundary?: RuntimeBoundaryCalls): Promise<PlaybookActorOutput>;
|
|
284
429
|
interface PlayerBridgeSpec {
|
|
285
430
|
resolveRoleId: (input: PlaybookPlayerInput) => string;
|
|
431
|
+
validateInput?: (input: PlaybookPlayerInput) => void;
|
|
286
432
|
composePlayerPrompt: (input: PlaybookPlayerInput) => string;
|
|
287
433
|
adjudication: PlayerAdjudicationSpec;
|
|
288
434
|
resumableStateIds: ReadonlySet<string>;
|
|
435
|
+
allowsCorrectiveReplay?: (result: PlayerResult) => boolean;
|
|
289
436
|
}
|
|
290
437
|
export declare function createPlayerBridge(spec: PlayerBridgeSpec, ports: PlaybookPorts, getActiveSignal?: () => AbortSignal | undefined, boundary?: RuntimeBoundaryCalls, onControlPlaneError?: (error: unknown) => void): PromiseActorLogic<PlaybookActorOutput, PlaybookPlayerInput>;
|
|
291
438
|
/**
|
|
@@ -311,11 +458,13 @@ export declare function stateDescriptionsFromMachine(machine: AnyStateMachine):
|
|
|
311
458
|
* under the slc/link.md contract. The factory provides every actor kind the
|
|
312
459
|
* machine declares — `player`, `script`, `captain`, and nested `playbook`
|
|
313
460
|
* (literal and dynamic) — and implements the full runtime lifecycle including
|
|
314
|
-
* the optional parked-session snapshot capability (DR-014)
|
|
461
|
+
* the optional parked-session snapshot capability (DR-014) and the retained-
|
|
462
|
+
* snapshot adoption capability (DR-038).
|
|
315
463
|
*
|
|
316
|
-
* Scope: machines
|
|
317
|
-
*
|
|
318
|
-
*
|
|
464
|
+
* Scope: flat single-region machines — no parallel state, no compound
|
|
465
|
+
* child states, and every root state's `meta.playbook.stateId` equal to its
|
|
466
|
+
* state key — so each snapshot exposes exactly one playbook state id.
|
|
467
|
+
* Parallel-region FSMs keep their own linked runtimes.
|
|
319
468
|
*/
|
|
320
|
-
export declare function createXStatePlaybookRuntime<TOptions>(machine: AnyStateMachine, spec:
|
|
469
|
+
export declare function createXStatePlaybookRuntime<TOptions, THostCapabilities extends object>(machine: AnyStateMachine, spec: XStatePlaybookRuntimeSpecV3<TOptions>): XStatePlaybookRuntimeFactory<XStatePlaybookRuntimeConstruction<TOptions, THostCapabilities>, 3>;
|
|
321
470
|
export {};
|