@sublang/playbook 9.0.0 → 10.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/cli.md +51 -8
- package/docs/embedding.md +38 -12
- 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 +140 -10
- package/reference/sdlc/captain.playbook/captain.playbook.ts +188 -16
- 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 +7 -0
- package/reference/sdlc/code.playbook/code.fsm.js +74 -25
- package/reference/sdlc/code.playbook/code.fsm.ts +83 -29
- 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 +54 -2
- package/reference/sdlc/code.playbook/code.playbook.ts +75 -6
- 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 +1850 -72
- package/reference/sdlc/code.playbook/playbook-captain.ts +2759 -96
- package/reference/sdlc/decide.md +0 -1
- package/reference/sdlc/decide.playbook/decide.fsm.d.ts +7 -0
- 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 +13 -5
- package/reference/sdlc/decide.playbook/decide.playbook.js +1712 -91
- package/reference/sdlc/decide.playbook/decide.playbook.ts +2677 -136
- 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 +65 -2
- package/reference/sdlc/review.playbook/review.playbook.ts +83 -6
- 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 +6 -5
- package/slc/link.md +544 -41
- 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 +164 -3
- package/src/runtime.ts +213 -2
- package/src/xstate-playbook-runtime.d.ts +149 -10
- package/src/xstate-playbook-runtime.js +2569 -270
- package/src/xstate-playbook-runtime.ts +4133 -490
- package/src/xstate-runtime.d.ts +59 -1
- package/src/xstate-runtime.js +866 -7
- package/src/xstate-runtime.ts +1397 -7
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;
|
|
@@ -174,6 +178,16 @@ export interface PlaybookSession {
|
|
|
174
178
|
ports: PlaybookPorts;
|
|
175
179
|
}
|
|
176
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
|
+
|
|
177
191
|
export type PlaybookTraceType =
|
|
178
192
|
| 'session.started'
|
|
179
193
|
| 'boss.input.received'
|
|
@@ -188,12 +202,13 @@ export type PlaybookTraceType =
|
|
|
188
202
|
| 'apply.started'
|
|
189
203
|
| 'apply.finished'
|
|
190
204
|
| 'fsm.transition'
|
|
205
|
+
| 'outcome.accepted'
|
|
191
206
|
| 'status.emitted'
|
|
192
207
|
| 'boss.input.settled'
|
|
193
208
|
| 'session.disposed';
|
|
194
209
|
|
|
195
210
|
export interface PlaybookTraceEvent {
|
|
196
|
-
schemaVersion:
|
|
211
|
+
schemaVersion: 4;
|
|
197
212
|
sessionId: string;
|
|
198
213
|
playbookId: string;
|
|
199
214
|
rootSessionId: string;
|
|
@@ -215,12 +230,164 @@ export interface PlaybookPendingBossQuestion {
|
|
|
215
230
|
sourceItem?: string;
|
|
216
231
|
}
|
|
217
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
|
+
|
|
218
385
|
// DR-014 §1 / DR-031 §5 / DR-032: JSON-safe capture of a parked or nested-call
|
|
219
386
|
// suspended session. `machine` is the opaque XState persisted snapshot;
|
|
220
387
|
// pending Boss questions and a suspended call are first-class so a
|
|
221
388
|
// host never has to reconstruct durable ownership from presentation records.
|
|
222
389
|
export interface PlaybookRuntimeSnapshot {
|
|
223
|
-
schemaVersion:
|
|
390
|
+
schemaVersion: 4;
|
|
224
391
|
playbookId: string;
|
|
225
392
|
machine: JsonValue;
|
|
226
393
|
roleResumeTokens: { readonly [roleId: string]: string };
|
|
@@ -234,6 +401,21 @@ export interface PlaybookRuntimeSnapshot {
|
|
|
234
401
|
};
|
|
235
402
|
state: PlaybookState;
|
|
236
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
|
+
};
|
|
237
419
|
suspendedCall?: PlaybookSuspendedCall;
|
|
238
420
|
}
|
|
239
421
|
|
|
@@ -269,6 +451,15 @@ export type PlaybookControlReceipt =
|
|
|
269
451
|
| { disposition: 'executed'; run: PlaybookRunResult }
|
|
270
452
|
| { disposition: 'failed'; error: NormalizedError };
|
|
271
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
|
+
|
|
272
463
|
export interface PlaybookRuntime {
|
|
273
464
|
init(session: PlaybookSession): Promise<void>;
|
|
274
465
|
// DR-014 §1 optional durable-session capability: a runtime implements
|
|
@@ -281,6 +472,16 @@ export interface PlaybookRuntime {
|
|
|
281
472
|
session: PlaybookSession,
|
|
282
473
|
snapshot: PlaybookRuntimeSnapshot,
|
|
283
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;
|
|
284
485
|
// DR-029 optional control-surface capability: a runtime implements
|
|
285
486
|
// both members or neither. `describe` is side-effect free and valid at
|
|
286
487
|
// parked quiescence outside an active boundary; `apply` revalidates the
|
|
@@ -289,6 +490,16 @@ export interface PlaybookRuntime {
|
|
|
289
490
|
// runtime lacking the pair advertises no actions; plain text delivery is
|
|
290
491
|
// the only verb against it.
|
|
291
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
|
+
)[];
|
|
292
503
|
apply?(input: {
|
|
293
504
|
actionId: string;
|
|
294
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. */
|
|
@@ -226,6 +352,8 @@ export interface XStatePlaybookRuntimeSpec<TOptions> {
|
|
|
226
352
|
* surfaced first-class by the view and shall not be named here.
|
|
227
353
|
*/
|
|
228
354
|
controlContextFields?: readonly string[];
|
|
355
|
+
/** Root final states whose terminal outcome leaves unfinished work. Default: none. */
|
|
356
|
+
unfinishedFinalStateIds?: ReadonlySet<string>;
|
|
229
357
|
/** States that may suspend for a Boss reply. Default: targets of the FSM's `awaitBossReply` BOSS_REPLY transitions. */
|
|
230
358
|
resumableStateIds?: ReadonlySet<string>;
|
|
231
359
|
/** Human status lines for a root transition. Default: guard, declared-player, question, and failure lines. */
|
|
@@ -237,6 +365,14 @@ export interface XStatePlaybookRuntimeSpec<TOptions> {
|
|
|
237
365
|
/** Working directory for `script` actors. Default: the validated options' string `cwd`, else the process working directory. */
|
|
238
366
|
scriptCwd?: (options: TOptions) => string | undefined;
|
|
239
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>;
|
|
240
376
|
/** Strip a single Markdown code fence that wraps the whole string. */
|
|
241
377
|
export declare function stripCodeFence(text: string): string;
|
|
242
378
|
export declare function extractJsonValue(text: string, start: number, repair: boolean): string | undefined;
|
|
@@ -292,9 +428,11 @@ export interface PlayerAdjudicationSpec {
|
|
|
292
428
|
export declare function adjudicatePlayerOutput(spec: PlayerAdjudicationSpec, input: PlaybookPlayerInput, finalText: string, ports: PlaybookPorts, signal: AbortSignal, boundary?: RuntimeBoundaryCalls): Promise<PlaybookActorOutput>;
|
|
293
429
|
interface PlayerBridgeSpec {
|
|
294
430
|
resolveRoleId: (input: PlaybookPlayerInput) => string;
|
|
431
|
+
validateInput?: (input: PlaybookPlayerInput) => void;
|
|
295
432
|
composePlayerPrompt: (input: PlaybookPlayerInput) => string;
|
|
296
433
|
adjudication: PlayerAdjudicationSpec;
|
|
297
434
|
resumableStateIds: ReadonlySet<string>;
|
|
435
|
+
allowsCorrectiveReplay?: (result: PlayerResult) => boolean;
|
|
298
436
|
}
|
|
299
437
|
export declare function createPlayerBridge(spec: PlayerBridgeSpec, ports: PlaybookPorts, getActiveSignal?: () => AbortSignal | undefined, boundary?: RuntimeBoundaryCalls, onControlPlaneError?: (error: unknown) => void): PromiseActorLogic<PlaybookActorOutput, PlaybookPlayerInput>;
|
|
300
438
|
/**
|
|
@@ -320,12 +458,13 @@ export declare function stateDescriptionsFromMachine(machine: AnyStateMachine):
|
|
|
320
458
|
* under the slc/link.md contract. The factory provides every actor kind the
|
|
321
459
|
* machine declares — `player`, `script`, `captain`, and nested `playbook`
|
|
322
460
|
* (literal and dynamic) — and implements the full runtime lifecycle including
|
|
323
|
-
* 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).
|
|
324
463
|
*
|
|
325
464
|
* Scope: flat single-region machines — no parallel state, no compound
|
|
326
465
|
* child states, and every root state's `meta.playbook.stateId` equal to its
|
|
327
466
|
* state key — so each snapshot exposes exactly one playbook state id.
|
|
328
467
|
* Parallel-region FSMs keep their own linked runtimes.
|
|
329
468
|
*/
|
|
330
|
-
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>;
|
|
331
470
|
export {};
|