@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/slc/link.md
CHANGED
|
@@ -39,7 +39,13 @@ The emitted module shall default-export a factory of the following shape:
|
|
|
39
39
|
|
|
40
40
|
```typescript
|
|
41
41
|
interface PlaybookRuntime {
|
|
42
|
+
readonly retainedGenerationMetadata?: PlaybookRetainedGenerationMetadata;
|
|
42
43
|
init(session: PlaybookSession): Promise<void>;
|
|
44
|
+
adopt?(
|
|
45
|
+
session: PlaybookSession,
|
|
46
|
+
snapshot: PlaybookRuntimeSnapshot,
|
|
47
|
+
context: PlaybookAdoptionContext,
|
|
48
|
+
): Promise<void>;
|
|
43
49
|
handleBossInput(turn: {
|
|
44
50
|
text: string;
|
|
45
51
|
signal: AbortSignal;
|
|
@@ -49,9 +55,23 @@ interface PlaybookRuntime {
|
|
|
49
55
|
result: PlaybookCallResult;
|
|
50
56
|
signal: AbortSignal;
|
|
51
57
|
}): Promise<PlaybookRunResult>;
|
|
58
|
+
unresolvedEffectEnvelopes?(): readonly (
|
|
59
|
+
| { readonly kind: 'boundary'; readonly boundaryId: string }
|
|
60
|
+
| { readonly kind: 'logical-operation'; readonly operationId: string }
|
|
61
|
+
)[];
|
|
52
62
|
dispose(): Promise<void>;
|
|
53
63
|
}
|
|
54
64
|
|
|
65
|
+
interface PlaybookRetainedGenerationMetadata {
|
|
66
|
+
readonly unfinishedFinalStateIds: readonly string[];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
interface PlaybookAdoptionContext {
|
|
70
|
+
readonly sourceSessionId: string;
|
|
71
|
+
readonly sourceGenerationId: string;
|
|
72
|
+
readonly targetChildSessionId?: string;
|
|
73
|
+
}
|
|
74
|
+
|
|
55
75
|
interface PlaybookSession {
|
|
56
76
|
sessionId: string;
|
|
57
77
|
playbookId: string;
|
|
@@ -121,10 +141,160 @@ interface PlaybookSuspendedCall extends PlaybookPendingCall {
|
|
|
121
141
|
stateId: string;
|
|
122
142
|
text: string;
|
|
123
143
|
turnId?: number;
|
|
144
|
+
effectBoundaryPrefixSequence?: number | null;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
type PlaybookRepositoryReceiptClassification =
|
|
148
|
+
| 'unchanged'
|
|
149
|
+
| 'one-descendant-commit'
|
|
150
|
+
| 'multiple-commits'
|
|
151
|
+
| 'rewritten-or-non-descendant'
|
|
152
|
+
| 'worktree-only-change'
|
|
153
|
+
| 'concurrent-or-foreign-change'
|
|
154
|
+
| 'observation-ambiguous';
|
|
155
|
+
|
|
156
|
+
interface PlaybookRepositoryObservation {
|
|
157
|
+
readonly worktree: string;
|
|
158
|
+
readonly gitDir: string;
|
|
159
|
+
readonly head: string;
|
|
160
|
+
readonly projection: Readonly<Record<string, JsonValue>>;
|
|
161
|
+
readonly projectionDigest: string;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
interface PlaybookRepositoryReceipt {
|
|
165
|
+
readonly classification: PlaybookRepositoryReceiptClassification;
|
|
166
|
+
readonly baseline: PlaybookRepositoryObservation;
|
|
167
|
+
readonly after?: PlaybookRepositoryObservation;
|
|
168
|
+
readonly commitOid?: string;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
type PlaybookRepositoryDisposition =
|
|
172
|
+
| 'unchanged'
|
|
173
|
+
| 'one-descendant-commit'
|
|
174
|
+
| 'deferred';
|
|
175
|
+
|
|
176
|
+
interface PlaybookEffectBoundary {
|
|
177
|
+
readonly sequence: number;
|
|
178
|
+
readonly boundaryId: string;
|
|
179
|
+
readonly attemptId: string;
|
|
180
|
+
readonly attemptNumber: number;
|
|
181
|
+
readonly playbookId: string;
|
|
182
|
+
readonly runtimeSessionId: string;
|
|
183
|
+
readonly turnId: number;
|
|
184
|
+
readonly callId: string;
|
|
185
|
+
readonly roleId: string;
|
|
186
|
+
readonly sourceStateId: string;
|
|
187
|
+
readonly sourceOutcomeSchema: JsonValue;
|
|
188
|
+
readonly dispositions: readonly PlaybookRepositoryDisposition[];
|
|
189
|
+
readonly canonicalWorktree: {
|
|
190
|
+
readonly worktree: string;
|
|
191
|
+
readonly gitDir: string;
|
|
192
|
+
};
|
|
193
|
+
readonly baseline: PlaybookRepositoryObservation;
|
|
194
|
+
readonly after?: PlaybookRepositoryObservation;
|
|
195
|
+
readonly physicalReceipt?: PlaybookRepositoryReceipt;
|
|
196
|
+
readonly finalText?: string;
|
|
197
|
+
readonly semanticCandidate?: JsonValue;
|
|
198
|
+
readonly initialSemanticCandidate?: JsonValue;
|
|
199
|
+
readonly correctionBudget: { readonly limit: 1; readonly spent: boolean };
|
|
200
|
+
readonly cohortId?: string;
|
|
201
|
+
readonly logicalOperationId?: string;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
interface PlaybookEffectLogicalOperation {
|
|
205
|
+
readonly sequence: number;
|
|
206
|
+
readonly operationId: string;
|
|
207
|
+
readonly playbookId: string;
|
|
208
|
+
readonly runtimeSessionId: string;
|
|
209
|
+
readonly boundaryIds: readonly string[];
|
|
210
|
+
readonly originalBaseline: PlaybookRepositoryObservation;
|
|
211
|
+
readonly checkpoint?: PlaybookRepositoryObservation;
|
|
212
|
+
readonly pendingQuestion?: PlaybookPendingBossQuestion;
|
|
213
|
+
readonly playerContinuation?: JsonValue;
|
|
214
|
+
readonly checkpointRestorationEligible: boolean;
|
|
215
|
+
readonly logicalReceipt?: PlaybookRepositoryReceipt;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
interface PlaybookEffectLedger {
|
|
219
|
+
readonly schemaVersion: 1;
|
|
220
|
+
readonly revision: number;
|
|
221
|
+
readonly boundaries: readonly PlaybookEffectBoundary[];
|
|
222
|
+
readonly logicalOperations: readonly PlaybookEffectLogicalOperation[];
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
type PlaybookEffectBoundaryStart = Omit<
|
|
226
|
+
PlaybookEffectBoundary,
|
|
227
|
+
| 'sequence'
|
|
228
|
+
| 'attemptId'
|
|
229
|
+
| 'attemptNumber'
|
|
230
|
+
| 'after'
|
|
231
|
+
| 'physicalReceipt'
|
|
232
|
+
| 'finalText'
|
|
233
|
+
| 'semanticCandidate'
|
|
234
|
+
| 'initialSemanticCandidate'
|
|
235
|
+
>;
|
|
236
|
+
|
|
237
|
+
type PlaybookEffectLogicalOperationStart = Omit<
|
|
238
|
+
PlaybookEffectLogicalOperation,
|
|
239
|
+
'sequence'
|
|
240
|
+
>;
|
|
241
|
+
|
|
242
|
+
type PlaybookEffectLedgerCommand =
|
|
243
|
+
| {
|
|
244
|
+
readonly kind: 'start-boundaries';
|
|
245
|
+
readonly boundaries: readonly [
|
|
246
|
+
PlaybookEffectBoundaryStart,
|
|
247
|
+
...PlaybookEffectBoundaryStart[],
|
|
248
|
+
];
|
|
249
|
+
}
|
|
250
|
+
| {
|
|
251
|
+
readonly kind: 'replace-boundaries';
|
|
252
|
+
readonly replacements: readonly [
|
|
253
|
+
{
|
|
254
|
+
readonly expected: PlaybookEffectBoundary;
|
|
255
|
+
readonly next: PlaybookEffectBoundary;
|
|
256
|
+
},
|
|
257
|
+
...{
|
|
258
|
+
readonly expected: PlaybookEffectBoundary;
|
|
259
|
+
readonly next: PlaybookEffectBoundary;
|
|
260
|
+
}[],
|
|
261
|
+
];
|
|
262
|
+
}
|
|
263
|
+
| {
|
|
264
|
+
readonly kind: 'append-logical-operations';
|
|
265
|
+
readonly operations: readonly [
|
|
266
|
+
PlaybookEffectLogicalOperationStart,
|
|
267
|
+
...PlaybookEffectLogicalOperationStart[],
|
|
268
|
+
];
|
|
269
|
+
}
|
|
270
|
+
| {
|
|
271
|
+
readonly kind: 'replace-logical-operations';
|
|
272
|
+
readonly replacements: readonly [
|
|
273
|
+
{
|
|
274
|
+
readonly expected: PlaybookEffectLogicalOperation;
|
|
275
|
+
readonly next: PlaybookEffectLogicalOperation;
|
|
276
|
+
},
|
|
277
|
+
...{
|
|
278
|
+
readonly expected: PlaybookEffectLogicalOperation;
|
|
279
|
+
readonly next: PlaybookEffectLogicalOperation;
|
|
280
|
+
}[],
|
|
281
|
+
];
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
type PlaybookEffectLedgerCommandBatch = readonly [
|
|
285
|
+
PlaybookEffectLedgerCommand,
|
|
286
|
+
...PlaybookEffectLedgerCommand[],
|
|
287
|
+
];
|
|
288
|
+
|
|
289
|
+
interface PlaybookEffectLedgerCapability {
|
|
290
|
+
snapshot(): PlaybookEffectLedger;
|
|
291
|
+
writeAhead(
|
|
292
|
+
commands: PlaybookEffectLedgerCommandBatch,
|
|
293
|
+
): Promise<PlaybookEffectLedger>;
|
|
124
294
|
}
|
|
125
295
|
|
|
126
296
|
interface PlaybookRuntimeSnapshot {
|
|
127
|
-
schemaVersion:
|
|
297
|
+
schemaVersion: 4;
|
|
128
298
|
playbookId: string;
|
|
129
299
|
machine: JsonValue;
|
|
130
300
|
roleResumeTokens: { readonly [roleId: string]: string };
|
|
@@ -138,11 +308,27 @@ interface PlaybookRuntimeSnapshot {
|
|
|
138
308
|
};
|
|
139
309
|
state: PlaybookState;
|
|
140
310
|
pendingBossQuestions: readonly PlaybookPendingBossQuestion[];
|
|
311
|
+
effectLedger: PlaybookEffectLedger;
|
|
312
|
+
/** Original runtime identity retained across schema-3 adoption lineage. */
|
|
313
|
+
retainedEffectSourceSessionId?: string;
|
|
314
|
+
/**
|
|
315
|
+
* Unsafe retained-adoption checkpoint. The marker remains durable until
|
|
316
|
+
* authoritative reconciliation proves its complete suffix replay-safe.
|
|
317
|
+
*/
|
|
318
|
+
retainedEffectReconciliation?: {
|
|
319
|
+
readonly sourceSessionId: string;
|
|
320
|
+
readonly checkpoint: PlaybookEffectLedger;
|
|
321
|
+
};
|
|
322
|
+
failedEffectAttempt?: {
|
|
323
|
+
readonly boundaryPrefix: number;
|
|
324
|
+
readonly attemptId: string | null;
|
|
325
|
+
};
|
|
141
326
|
suspendedCall?: PlaybookSuspendedCall;
|
|
142
327
|
}
|
|
143
328
|
|
|
144
329
|
type PlaybookRunResult =
|
|
145
330
|
| { outcome: 'quiescent' | 'no-action'; state: PlaybookState }
|
|
331
|
+
| { outcome: 'unresolved-effect'; state: PlaybookState }
|
|
146
332
|
| {
|
|
147
333
|
outcome: 'failed' | 'aborted';
|
|
148
334
|
state: PlaybookState;
|
|
@@ -165,11 +351,80 @@ type PlaybookRuntimeFactory<Options = unknown> = (
|
|
|
165
351
|
) => PlaybookRuntime;
|
|
166
352
|
|
|
167
353
|
export default function createPlaybookRuntime(
|
|
168
|
-
|
|
354
|
+
construction: XStatePlaybookRuntimeConstruction<
|
|
355
|
+
PlaybookRuntimeOptions,
|
|
356
|
+
HostCapabilities
|
|
357
|
+
>,
|
|
169
358
|
): PlaybookRuntime;
|
|
170
359
|
```
|
|
171
360
|
|
|
172
|
-
|
|
361
|
+
For a Captain-hosted linked workflow, the default export conforms to `PlaybookRuntimeFactory<XStatePlaybookRuntimeConstruction<PlaybookRuntimeOptions, HostCapabilities>>`, where `HostCapabilities` is the artifact's exact live schema-3 capability type and `PlaybookRuntimeFactory` is the generic factory type the shared contract module exposes (§Output).
|
|
362
|
+
The roleless session-Captain is the sole signature exception: its public options-only `PlaybookRuntimeFactory<PlaybookRuntimeOptions>` wrapper supplies its fixed empty-ledger, fail-closed schema-3 capabilities internally because no Captain host exists above it.
|
|
363
|
+
|
|
364
|
+
Artifact schema `3` shall require `outcomeAuthority` as an own plain-JSON data property and shall instantiate the shared factory with exactly `{ configuredOptions, hostCapabilities }`, where `configuredOptions` is the registry-validated plain-JSON workflow slice and `hostCapabilities` is a non-null live current-host object.
|
|
365
|
+
For schema `3`, the `Options` argument of the one-argument shared `PlaybookRuntimeFactory<Options>` shall be `XStatePlaybookRuntimeConstruction<ConfiguredOptions, HostCapabilities>`; the registry's public entry receives the two members separately and composes that one internal argument only at the artifact boundary.
|
|
366
|
+
For a Captain-hosted schema-3 artifact, `hostCapabilities` shall contain exactly `authority`, `repository`, and `effectLedger`: authority binds that artifact's id, schema, detached role and cohort declarations, current configured working directory, logical session and lease-owner identities, and canonical worktree; repository exposes that same canonical identity plus host-bound observation, acquisition, exclusive-call, and cohort operations, whose optional live completion mapper may return only detached `finalText`, `semanticCandidate`, `logicalOperationId`, and additional typed ledger commands for the same atomic completion; and the ledger exposes its synchronous detached `snapshot(): PlaybookEffectLedger` mirror plus `writeAhead(commands: PlaybookEffectLedgerCommandBatch): Promise<PlaybookEffectLedger>` against the current host's atomic writer.
|
|
367
|
+
Only `configuredOptions` may reach option snapshotting and FSM input.
|
|
368
|
+
The capability object, its callbacks, lease token, and live claim or store handles shall enter neither `PlaybookPorts`, machine input or context, runtime snapshots, launch or durable projections, retained generations, nor continuation identity; the detached ledger data and canonical identities returned by its ledger channel shall instead persist only through the versioned effect-ledger members defined below.
|
|
369
|
+
|
|
370
|
+
```typescript
|
|
371
|
+
type XStateOutcomeFieldAuthority =
|
|
372
|
+
| 'presentation'
|
|
373
|
+
| 'semantic'
|
|
374
|
+
| 'effect'
|
|
375
|
+
| 'runtime';
|
|
376
|
+
|
|
377
|
+
type XStateRepositoryDisposition =
|
|
378
|
+
| 'unchanged'
|
|
379
|
+
| 'one-descendant-commit'
|
|
380
|
+
| 'deferred';
|
|
381
|
+
|
|
382
|
+
interface XStateGovernedOutcomeSpec {
|
|
383
|
+
readonly fields: Readonly<Record<string, XStateOutcomeFieldAuthority>>;
|
|
384
|
+
readonly repositoryDisposition: XStateRepositoryDisposition;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
interface XStateOutcomeAuthoritySpec {
|
|
388
|
+
readonly governedPlayerStates: Readonly<
|
|
389
|
+
Record<
|
|
390
|
+
string,
|
|
391
|
+
Readonly<Record<string, XStateGovernedOutcomeSpec>>
|
|
392
|
+
>
|
|
393
|
+
>;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
interface XStatePlaybookRuntimeConstruction<
|
|
397
|
+
ConfiguredOptions,
|
|
398
|
+
HostCapabilities extends object,
|
|
399
|
+
> {
|
|
400
|
+
readonly configuredOptions: ConfiguredOptions;
|
|
401
|
+
readonly hostCapabilities: HostCapabilities & {
|
|
402
|
+
readonly effectLedger: PlaybookEffectLedgerCapability;
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
The shared type-only contract module shall export `PlaybookRepositoryDisposition`, `PlaybookRepositoryObservation`, `PlaybookRepositoryReceipt`, `PlaybookEffectBoundary`, `PlaybookEffectBoundaryStart`, `PlaybookEffectLogicalOperation`, `PlaybookEffectLedger`, `PlaybookEffectLedgerCommand`, `PlaybookEffectLedgerCommandBatch`, and `PlaybookEffectLedgerCapability`; the executable `@sublang/playbook/xstate-runtime` module shall export `assertPlaybookEffectLedger`, `emptyPlaybookEffectLedger`, and `isPlaybookEffectLedgerMonotonicExtension` over those types.
|
|
408
|
+
That executable module shall also export the centralized schema-3 semantic surface: `PlaybookSemanticFieldAuthority`, `PlaybookSemanticOutcomeSpec`, `PlaybookSemanticEvidenceInput`, `PlaybookReconciledSemanticOutput`, `PlaybookRetainedSemanticEvidence`, `PlaybookSemanticReconciliationReason`, `PlaybookSemanticReconciliation`, `PlaybookSemanticCandidateStructureError`, and `reconcilePlaybookSemanticEvidence`.
|
|
409
|
+
The pure reconciler shall accept the declared state-local outcomes, an unknown semantic candidate, and optional unknown `finalText`, repository receipt, and runtime-field evidence; shall return a detached frozen `resolved` or `deferred` decision with exact output and retained evidence, or an `unresolved` decision with retained evidence and one closed reason from `missing-presentation-evidence`, `missing-repository-receipt`, `invalid-repository-receipt`, `repository-disposition-mismatch`, `missing-effect-evidence`, `missing-runtime-evidence`, and `inconsistent-runtime-evidence`; and shall reserve `PlaybookSemanticCandidateStructureError` for candidate defects eligible for the bounded correction path rather than effect-evidence disagreement.
|
|
410
|
+
The empty ledger shall be exactly `{ schemaVersion: 1, revision: 0, boundaries: [], logicalOperations: [] }`, and revision shall be zero if and only if both ordered ledgers are empty.
|
|
411
|
+
The validator shall capture the complete supplied ledger once as detached frozen JSON and enforce every closed member, identity, ordering, receipt, cross-reference, correction-budget, and logical-operation invariant represented above.
|
|
412
|
+
One optional host-owned UUID `cohortId` shall identify every member of exactly one contiguous, distinct-role, all-`unchanged` physical cohort in declared role order; every member shall share attempt, playbook, runtime-session, turn, canonical-worktree, and baseline identity and shall be uniformly started or uniformly complete, complete members shall carry the identical after observation and receipt, and the id shall never be reused by another group.
|
|
413
|
+
Within a logical operation, `checkpoint`, `pendingQuestion`, and `playerContinuation` shall be all present or all absent; the pending question shall preserve its exact nonempty authored identity and nonblank content, and `checkpointRestorationEligible: true` shall require that complete bound group.
|
|
414
|
+
Each logical operation shall reciprocally name every and only boundary carrying its operation id, share those boundaries' playbook and runtime-session identity, and use its first boundary's exact baseline as `originalBaseline`; every linked boundary shall use that baseline's canonical worktree and, after the first, start from the preceding boundary's complete after checkpoint, while a logical receipt shall require every linked physical receipt.
|
|
415
|
+
`isPlaybookEffectLedgerMonotonicExtension(checkpoint, current)` shall accept exact equality and only a ledger reachable through the typed append-or-replace transitions without boundary or operation deletion, identity or original-baseline reassignment, correction-budget replenishment, completed-receipt or evidence loss, or removal or reordering of an earlier boundary-id prefix. A spent correction may replace `semanticCandidate` exactly once only while adding `initialSemanticCandidate` equal to the prior candidate; that initial candidate then remains immutable. A replacement may append boundary ids and replace or clear the complete current checkpoint, pending-question, and player-continuation group together with its eligibility, while an existing logical receipt remains immutable ([DR-040](../specs/decisions/040-outcome-authority-effect-reconciliation.md)).
|
|
416
|
+
Every accepted non-idempotent command batch shall increment revision once; an exact start or append replay under the same boundary or operation identities and payload shall return the same acknowledged ledger, while conflicting identity reuse shall reject without mutation.
|
|
417
|
+
The host shall assign each started boundary's sequence, current uncertain-attempt UUID, and positive attempt number, and shall assign each appended logical operation's sequence.
|
|
418
|
+
Every command batch and every command's entry list shall be nonempty; the host shall apply its commands in order as one ledger transition, perform final cross-reference validation after the complete batch, and acknowledge only one atomic persistence and revision increment.
|
|
419
|
+
Every replace command's exact `{ expected, next }` pair shall compare-and-swap one present boundary or operation, preserve its identity and immutable fields, reject a stale expected value, and move optional evidence, the one-way correction budget, or the current logical binding and eligibility only as permitted by DR-040.
|
|
420
|
+
After a governed operation settles, the host shall retain any exact proposed completion batch only in live memory until it is acknowledged and the cooperative claim retires; an indeterminate same-process write shall retry or recognize that batch under the still-owned claim, while recovery after process death shall reconstruct only evidence provable from the durable baseline and current repository observation before source restoration.
|
|
421
|
+
|
|
422
|
+
`governedPlayerStates` shall name every delegated-player state declared by `roleStates`, or shall be exactly empty for an artifact with no delegated-player state; it shall name no other state.
|
|
423
|
+
Each state shall name exactly the outcomes in that state's `invoke.input.result`, and each outcome shall contain exactly `fields` and `repositoryDisposition`.
|
|
424
|
+
The outcome key owns the semantic discriminator, so `guard` shall not appear in `fields`; the `fields` keys shall equal every additional payload field named by that outcome's result description.
|
|
425
|
+
Each field shall have exactly one authority from `presentation`, `semantic`, `effect`, or `runtime`; every linker-declared verbatim payload field and `question` shall be `presentation`, `latestCommit` shall be `effect`, and the payload fields `irNumber` and `irTask` shall be `semantic`, while outcome keys such as `moreTasks` and `finalTask` remain semantic discriminators.
|
|
426
|
+
Each repository disposition shall be exactly `unchanged`, `one-descendant-commit`, or `deferred`; an effect-owned field is valid only on `one-descendant-commit`, and `deferred` is valid only on `needsBossReply` with presentation-owned `question` and another outcome in that state declaring `one-descendant-commit`.
|
|
427
|
+
The shared factory shall reject every legacy artifact schema and reject schema-3 missing, extra, unknown, wrongly owned, or inconsistent metadata before the affected player call.
|
|
173
428
|
|
|
174
429
|
`init` receives the host-owned playbook session identity and ports, constructs the XState actor with FSM `input` derived from `options`, and starts the actor.
|
|
175
430
|
The runtime owns the actor for its lifetime; `handleBossInput` runs one turn, and `dispose` stops the actor and drains pending port emissions.
|
|
@@ -192,7 +447,7 @@ Only the terminal variant may carry `stateDescription`; the runtime shall omit i
|
|
|
192
447
|
Control-plane exceptions reject the runtime method rather than masquerade as a
|
|
193
448
|
recoverable workflow `failed` result.
|
|
194
449
|
|
|
195
|
-
|
|
450
|
+
Configured options shall be plain JSON and live host seams shall enter only through `hostCapabilities` in the disjoint schema-3 construction input above.
|
|
196
451
|
The link compiler emits a typed options interface per playbook based on the FSM's `CodingInput` (or equivalent).
|
|
197
452
|
The CLI's absence of `--link-option` values does not mean that
|
|
198
453
|
`PlaybookRuntimeOptions` is empty. CLI link options are compile-time inputs;
|
|
@@ -288,6 +543,8 @@ type PlaybookCallStart =
|
|
|
288
543
|
| { state: 'suspended'; childSessionId: string };
|
|
289
544
|
```
|
|
290
545
|
|
|
546
|
+
A runtime's `{ outcome: 'unresolved-effect', state }` abandonment result is not a `PlaybookCallResult`: a host shall not translate it into child output or error, resume a parent FSM with it, or treat it as authored completion.
|
|
547
|
+
|
|
291
548
|
`PlayerResult` mirrors the status, resume token, final text, and error fields of cligent's `PlayerRunResult` ([TMUX-033](https://github.com/sublang-ai/cligent/blob/main/specs/user/tmux-play.md#tmux-033)).
|
|
292
549
|
The runtime treats `status !== 'ok'` as a player failure and routes it through the FSM's error path (§Abort).
|
|
293
550
|
An `ok` player result whose `finalText` is missing, empty, or whitespace-only
|
|
@@ -389,7 +646,7 @@ The runtime never speaks to LLMs directly and never touches host types beyond `P
|
|
|
389
646
|
## Playbook trace
|
|
390
647
|
|
|
391
648
|
Every linked runtime shall emit a boundary-complete, ordered trace through `emitTelemetry` topic `playbook.trace`.
|
|
392
|
-
Each payload shall carry `schemaVersion:
|
|
649
|
+
Each payload shall carry `schemaVersion: 4`, the immutable session identity and
|
|
393
650
|
causality, a contiguous one-based `sequence`, a Unix-millisecond `timestamp`, a
|
|
394
651
|
trace `type`, event `payload`, and the runtime-local `turnId` / paired `callId`
|
|
395
652
|
where applicable.
|
|
@@ -409,12 +666,13 @@ type PlaybookTraceType =
|
|
|
409
666
|
| 'apply.started'
|
|
410
667
|
| 'apply.finished'
|
|
411
668
|
| 'fsm.transition'
|
|
669
|
+
| 'outcome.accepted'
|
|
412
670
|
| 'status.emitted'
|
|
413
671
|
| 'boss.input.settled'
|
|
414
672
|
| 'session.disposed';
|
|
415
673
|
|
|
416
674
|
interface PlaybookTraceEvent {
|
|
417
|
-
schemaVersion:
|
|
675
|
+
schemaVersion: 4;
|
|
418
676
|
sessionId: string;
|
|
419
677
|
playbookId: string;
|
|
420
678
|
rootSessionId: string;
|
|
@@ -440,8 +698,9 @@ The trace types are `session.started`, `boss.input.received`,
|
|
|
440
698
|
`player.call.finished`, `captain.call.started`, `captain.call.finished`,
|
|
441
699
|
`playbook.call.started`,
|
|
442
700
|
`playbook.call.finished`, `apply.started`, `apply.finished`,
|
|
443
|
-
`fsm.transition`, `status.emitted`,
|
|
701
|
+
`fsm.transition`, `outcome.accepted`, `status.emitted`,
|
|
444
702
|
`boss.input.settled`, and `session.disposed`.
|
|
703
|
+
No trace event whose `schemaVersion` is below `4` is authority-bearing accepted-outcome evidence.
|
|
445
704
|
Call pairs carry exact prompts and replies, normalized failures, actor and state
|
|
446
705
|
identity, and their boundary-specific options.
|
|
447
706
|
`apply.started` and `apply.finished` are the paired apply boundary of a
|
|
@@ -456,8 +715,13 @@ Direct-Captain start and finish payloads shall carry `allowedTools` exactly when
|
|
|
456
715
|
the originating `CaptainCallOptions` selects it and shall omit the member when
|
|
457
716
|
the call preserves the host Captain's configured tools.
|
|
458
717
|
`session.started` and `session.disposed` carry their descriptor as top-level
|
|
459
|
-
`state` and its singular `stateId` when present.
|
|
460
|
-
|
|
718
|
+
`state` and its singular `stateId` when present. An adopted runtime begins its
|
|
719
|
+
fresh target trace with `session.started` at sequence `1`; that event also
|
|
720
|
+
carries an exact nested `adoption` object with `sourceSessionId` and
|
|
721
|
+
`sourceGenerationId`, plus the source/target call and child-session identities
|
|
722
|
+
when a suspended edge was rebased. The suspended form carries the fresh target
|
|
723
|
+
call id as top-level `callId` and carries no source `turnId`. Every judge start
|
|
724
|
+
and finish carries the working snapshot's singular `stateId` when one exists;
|
|
461
725
|
classification uses the current descriptor and adjudication uses the invoking
|
|
462
726
|
actor input. The default Captain always has such a singular id, while a
|
|
463
727
|
parallel snapshot may omit it. Every judge finish also carries
|
|
@@ -518,6 +782,7 @@ result: its outcome must be one of the `PlaybookRunResult` discriminants (never
|
|
|
518
782
|
an invented `error` outcome), and it shall include `state`, singular
|
|
519
783
|
`stateId`, `pendingCall`, `output`, and normalized `error` whenever the matching
|
|
520
784
|
result arm carries them.
|
|
785
|
+
The `unresolved-effect` arm shall carry only `state`; bounded repository-effect evidence remains host-owned and shall enter neither that result nor its trace projection.
|
|
521
786
|
One runtime-owned concurrency-one emission queue shall serialize every trace,
|
|
522
787
|
human status, and state telemetry call. Sequence allocation and enqueueing
|
|
523
788
|
shall occur atomically, and every public method shall drain that queue before
|
|
@@ -787,7 +1052,8 @@ clause (or equivalent typed output metadata). Backticked prose before that
|
|
|
787
1052
|
clause can name statuses, guards, or concepts such as `ok`, `aborted`, and
|
|
788
1053
|
`error`; those names are not output properties and shall never become required
|
|
789
1054
|
judge fields.
|
|
790
|
-
For a delegated-player field annotated exactly `` `<field>: <verbatim final text>` ``, the judge shall select the guard but the runtime shall replace any judge-supplied value with the player's canonical non-empty final text before returning the actor output.
|
|
1055
|
+
For a nongoverned delegated-player field annotated exactly `` `<field>: <verbatim final text>` ``, the judge shall select the guard but the runtime shall replace any judge-supplied value with the player's canonical non-empty final text before returning the actor output.
|
|
1056
|
+
For an artifact-schema-3 governed field, that annotation instead declares presentation authority and any judge-supplied value is a structural error under the authority rule below.
|
|
791
1057
|
The linker shall derive the complete `verbatimPayloadFields` set from those annotations across the FSM result maps.
|
|
792
1058
|
A field name that is annotated in one result map and unannotated in another is a link error because the shared adjudication strategy cannot give one property both ownership policies.
|
|
793
1059
|
For a direct Captain result, `question` and `response` are human-presentation
|
|
@@ -800,13 +1066,87 @@ After validating that selection, the runtime shall inject the exact non-empty
|
|
|
800
1066
|
It shall reject a judge reply that supplies either presentation field as an
|
|
801
1067
|
undeclared extra key, so hidden adjudication cannot replace, paraphrase, or
|
|
802
1068
|
decorate prose Boss already saw.
|
|
803
|
-
|
|
804
|
-
|
|
1069
|
+
For an artifact-schema-3 governed delegated-player call, the shared engine
|
|
1070
|
+
shall instead use one semantic reconciler for both the default linked runtime
|
|
1071
|
+
and any bespoke linked runtime that adopts schema `3`.
|
|
1072
|
+
That reconciler shall retain the validated player's exact non-empty
|
|
1073
|
+
`finalText` as opaque presentation evidence, let the hidden adjudicator read
|
|
1074
|
+
it only as semantic evidence, and require the adjudicator's detached
|
|
1075
|
+
plain-JSON candidate to contain exactly `guard` plus every and only
|
|
1076
|
+
semantic-owned payload field declared for that guard.
|
|
1077
|
+
The candidate shall therefore contain no presentation-, effect-, or
|
|
1078
|
+
runtime-owned payload field; `guard` shall name exactly one outcome declared
|
|
1079
|
+
by both the live result map and `outcomeAuthority`; and every semantic-owned
|
|
1080
|
+
field shall satisfy the result map's required-field type before any actor
|
|
1081
|
+
output is delivered.
|
|
1082
|
+
The reconciler shall construct the complete actor output rather than accept a
|
|
1083
|
+
cross-authority object from the judge: every presentation-owned payload field
|
|
1084
|
+
shall receive the canonical `finalText.trim()` value, effect-owned
|
|
1085
|
+
`latestCommit` shall receive only the qualifying receipt's exact commit OID,
|
|
1086
|
+
and no authority may supply, overwrite, or contradict another authority's
|
|
1087
|
+
field.
|
|
1088
|
+
It shall reject an absent required field, an undeclared or extra field, a
|
|
1089
|
+
field supplied by the wrong authority, an invalid value, or any mutually
|
|
1090
|
+
inconsistent candidate before FSM delivery.
|
|
1091
|
+
|
|
1092
|
+
For a non-deferred candidate, reconciliation shall require a complete durable
|
|
1093
|
+
physical receipt, or the complete cumulative logical receipt of a deferred
|
|
1094
|
+
operation, whose classification is exactly the outcome's declared
|
|
1095
|
+
`unchanged` or `one-descendant-commit` disposition; the latter shall carry
|
|
1096
|
+
exactly the after-HEAD OID used for `latestCommit`.
|
|
1097
|
+
A `deferred` candidate shall be admissible only for its already-validated
|
|
1098
|
+
effect-authorized `needsBossReply` outcome and only from a complete after
|
|
1099
|
+
observation whose HEAD equals the logical operation's original baseline HEAD
|
|
1100
|
+
and whose classification is exactly `unchanged` or `worktree-only-change`.
|
|
1101
|
+
It shall become deliverable only after the current host durably acknowledges
|
|
1102
|
+
the exact checkpoint, question, continuation, and logical-operation binding
|
|
1103
|
+
defined above; a missing checkpoint, changed HEAD, multiple or rewritten
|
|
1104
|
+
history, detected concurrent or foreign change, or ambiguous observation
|
|
1105
|
+
shall leave it unresolved.
|
|
1106
|
+
|
|
1107
|
+
The first structurally invalid schema-3 semantic reply shall make at most one
|
|
1108
|
+
corrective hidden adjudication eligible over the identical retained
|
|
1109
|
+
presentation evidence and declared outcome schema, with the validation error
|
|
1110
|
+
restated.
|
|
1111
|
+
Before starting that corrective judge, the runtime shall compare-and-swap the
|
|
1112
|
+
boundary's `correctionBudget` from `{ limit: 1, spent: false }` to
|
|
1113
|
+
`{ limit: 1, spent: true }` while atomically retaining its receipt, opaque
|
|
1114
|
+
presentation, and first recoverable invalid `semanticCandidate` through
|
|
1115
|
+
`effectLedger.writeAhead`, await the durable acknowledgement, replace its
|
|
1116
|
+
mirror with that acknowledged ledger, and check the applicable abort signal
|
|
1117
|
+
again.
|
|
1118
|
+
A failed or indeterminate spend, an acknowledgement that does not contain the
|
|
1119
|
+
exact one-way update, a previously spent budget, or an abort before the call
|
|
1120
|
+
begins shall start no corrective judge; the spent value shall remain spent
|
|
1121
|
+
across export, restore, adoption, and process restart.
|
|
1122
|
+
A second structurally invalid reply shall receive no further correction.
|
|
1123
|
+
A player abort, error, non-`ok` result, or missing non-empty `finalText` shall
|
|
1124
|
+
start no adjudication, while an initial or corrective judge transport failure
|
|
1125
|
+
or invalid host result shall start no corrective or third judge respectively.
|
|
1126
|
+
|
|
1127
|
+
Only a complete, authority-consistent semantic-and-effect envelope shall be
|
|
1128
|
+
delivered once to the FSM, and only after its evidence and applicable
|
|
1129
|
+
correction-budget or deferred-operation updates are durably acknowledged.
|
|
1130
|
+
The completion path shall retain the opaque `finalText`, the latest recoverable
|
|
1131
|
+
detached plain-JSON semantic candidate even when it is structurally invalid,
|
|
1132
|
+
and the receipt and correction budget without parsing the presentation for a
|
|
1133
|
+
repository fact; where a correction replaces that candidate, immutable
|
|
1134
|
+
`initialSemanticCandidate` shall preserve the candidate that consumed the
|
|
1135
|
+
budget, while a malformed reply from which no JSON value can be recovered may
|
|
1136
|
+
omit both candidates.
|
|
1137
|
+
An effect-possible envelope whose presentation, semantic, effect, or deferred
|
|
1138
|
+
checkpoint evidence is absent, invalid, incomplete, or inconsistent shall
|
|
1139
|
+
deliver no actor output and shall remain parked for later reconciliation;
|
|
1140
|
+
once its matching source state is restored, reconstruction from a durable
|
|
1141
|
+
complete envelope may perform that same reconciliation once without another
|
|
1142
|
+
player or judge call.
|
|
805
1143
|
The adjudicator shall use the same document-order tolerant JSON recovery as
|
|
806
1144
|
the Boss classifier. Unlike invalid classification, a reply from which no
|
|
807
1145
|
object can be recovered, an undeclared guard, or a missing required field is a
|
|
808
|
-
control-plane error
|
|
809
|
-
path and ordered
|
|
1146
|
+
control-plane error for nongoverned delegated-player and direct-Captain adjudication and
|
|
1147
|
+
shall throw after the invocation reaches its FSM error path and ordered
|
|
1148
|
+
emissions drain; schema-3 governed adjudication follows the bounded
|
|
1149
|
+
reconciliation contract above instead.
|
|
810
1150
|
|
|
811
1151
|
Two default adjudication strategies, in selection order:
|
|
812
1152
|
|
|
@@ -814,9 +1154,11 @@ Two default adjudication strategies, in selection order:
|
|
|
814
1154
|
names the source item's actor (and delegated player where applicable),
|
|
815
1155
|
includes the actor's verbatim output,
|
|
816
1156
|
lists the `result` keys with their descriptions, and demands a JSON
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
`
|
|
1157
|
+
answer keyed to exactly one of the declared guards: a nongoverned player uses
|
|
1158
|
+
`{ guard, …structuralPayloadFields }`, while a governed schema-3 player uses
|
|
1159
|
+
`{ guard, …semanticOwnedPayloadFields }` and explicitly forbids every other
|
|
1160
|
+
payload field. Both forms exclude the runtime-injected direct-Captain
|
|
1161
|
+
`question` and `response` fields above. The prompt shall identify hidden control work,
|
|
820
1162
|
prohibit tool use, file inspection, and external evidence, direct the judge
|
|
821
1163
|
to decide only from the supplied actor output and declared outcomes, and
|
|
822
1164
|
require exactly one JSON object with no prose. The judge prompt shall not
|
|
@@ -889,7 +1231,7 @@ the `{ visibility: 'visible', resume: false }` workflow-call selection
|
|
|
889
1231
|
(§PlaybookPorts contract, §Captain prompt composition) stay the
|
|
890
1232
|
visible-presentation shape for non-controller playbooks.
|
|
891
1233
|
|
|
892
|
-
The adjudicator shall fail loudly on:
|
|
1234
|
+
The nongoverned player adjudicator and every direct-Captain adjudicator shall fail loudly on:
|
|
893
1235
|
|
|
894
1236
|
- A guard the state does not declare,
|
|
895
1237
|
- A missing payload field the state's `result` description requires,
|
|
@@ -901,7 +1243,7 @@ identify an undeclared guard, and an incomplete selection shall identify the
|
|
|
901
1243
|
missing required field. A generic “no declared guard selected” error for all
|
|
902
1244
|
three cases is nonconformant.
|
|
903
1245
|
|
|
904
|
-
|
|
1246
|
+
Those adjudicator failures are control-plane errors.
|
|
905
1247
|
The runtime shall propagate them by throwing out of `handleBossInput` after attempting cleanup.
|
|
906
1248
|
The host adapter surfaces the throw on its control-plane channel (cligent surfaces such throws as `runtime_error` per [TMUX-025](https://github.com/sublang-ai/cligent/blob/main/specs/user/tmux-play.md#tmux-025)).
|
|
907
1249
|
The host's player-result channels (`player_finished` and equivalents) are reserved for failures the player itself produced; the host emits them when `callPlayer` resolves with `status !== 'ok'`.
|
|
@@ -911,11 +1253,12 @@ failure path specified above. Captain transport, result-shape, trace-sink, and
|
|
|
911
1253
|
adjudication failures remain control-plane errors unless the transport failure
|
|
912
1254
|
is causally identical to the active abort signal.
|
|
913
1255
|
Because XState still needs the invoked promise to settle, the linked runtime
|
|
914
|
-
shall latch
|
|
1256
|
+
shall latch a nongoverned delegated-player or direct-Captain adjudicator failure, actor-output JSON-validation, or nested-boundary
|
|
915
1257
|
control error outside machine context, allow the invocation's `onError` path to
|
|
916
1258
|
reach quiescence, drain all emissions, and then reject the public runtime
|
|
917
1259
|
method with that original error. It shall not return such a failure as a
|
|
918
1260
|
recoverable `{ outcome: 'failed' }` workflow result.
|
|
1261
|
+
An artifact-schema-3 governed-player adjudicator shall instead use the bounded structural correction, authority reconciliation, and unresolved parking contract above.
|
|
919
1262
|
The first latched non-abort control error takes precedence over a coincident
|
|
920
1263
|
boundary-signal abort. Read and clear the latch only in the public boundary's
|
|
921
1264
|
`finally` cleanup after XState and emissions have settled, so it cannot leak
|
|
@@ -1279,18 +1622,22 @@ The `PlaybookRuntime` shall:
|
|
|
1279
1622
|
The actor's `lastError` field shall be surfaced via `emitStatus` when the machine enters its `failed` state.
|
|
1280
1623
|
Presence of linker-emitted `roleStates` selects the canonical factory-backed status profile.
|
|
1281
1624
|
That profile shall emit the selected Boss event type
|
|
1282
|
-
before sending that event
|
|
1283
|
-
rider)
|
|
1625
|
+
before sending that event; exactly `→ <acceptedOutcome>` (with no payload-count or tally
|
|
1626
|
+
rider) only from a confirmed accepted-outcome marker; and
|
|
1284
1627
|
`⤷ <Role>: <label>` only when the entered state appears in the linked module's `roleStates` metadata.
|
|
1285
1628
|
It shall emit no raw state-id fallback for any other state.
|
|
1286
1629
|
`roleStates` shall be a complete map of the FSM states
|
|
1287
|
-
that invoke the typed `player` actor; each
|
|
1630
|
+
that invoke the typed `player` actor; each value carries the exact
|
|
1288
1631
|
local role from that state's source-derived `meta.playbook.role` and the state's exact FSM description as `{ role, label }`.
|
|
1289
1632
|
The factory shall reject an
|
|
1290
1633
|
incomplete entry, a non-player state, or a role or label that differs from the FSM metadata.
|
|
1291
1634
|
Artifact schema `1` and a missing compatibility declaration
|
|
1292
1635
|
shall reject before interpretation because their legacy `player` values may
|
|
1293
1636
|
encode bindings or aliases rather than canonical local roles.
|
|
1637
|
+
For artifact schema `3`, an accepted-outcome marker is a root-machine XState action with exact type `playbook.acceptedOutcome` and exact plain-data params `{ source, target, acceptedOutcome }` naming a declared governed outcome.
|
|
1638
|
+
The runtime shall observe that action only through the public root `@xstate.action` inspection event, retain it privately until the corresponding next public root `@xstate.snapshot` confirms `source` active in the prior snapshot and `target` active in the new snapshot, then emit one trace-schema-4 `outcome.accepted` event with those exact params before its canonical status and before public settlement; markers confirmed together shall retain their XState execution order.
|
|
1639
|
+
A valid unmarked transition, including an unexecuted guarded arm or rejected-guard fallback, shall settle normally with neither accepted-outcome evidence nor claimed-outcome status.
|
|
1640
|
+
An executed marker that is malformed, undeclared, or unconfirmed by those adjacent snapshots, or a batch that instruments one governed source more than once regardless of target or outcome, shall clear the entire pending marker batch and fail the current public boundary after retaining the ordinary transitioned state but before settlement, accepted-outcome evidence, or claimed-outcome status.
|
|
1294
1641
|
For the default Captain runtime, an initial `ready` state and a terminal `done`
|
|
1295
1642
|
state shall not emit human status. The terminal response is already visible
|
|
1296
1643
|
Captain prose; a synthetic “entered done” message would present it twice.
|
|
@@ -1333,18 +1680,22 @@ quiescent state with actor status `active`.
|
|
|
1333
1680
|
At a safe capture point it shall return a JSON-safe
|
|
1334
1681
|
`PlaybookRuntimeSnapshot` carrying:
|
|
1335
1682
|
|
|
1336
|
-
- `schemaVersion`: literal `
|
|
1683
|
+
- `schemaVersion`: literal `4`.
|
|
1337
1684
|
- `playbookId`: the bound session's playbook id.
|
|
1338
1685
|
- `machine`: the root actor's `getPersistedSnapshot()` result, passed
|
|
1339
1686
|
through the shared JSON detachment with any raw `Error` context value
|
|
1340
1687
|
(for example FSM `lastError`) normalized to `{ name, message, stack? }`
|
|
1341
1688
|
first. The value is opaque to hosts.
|
|
1689
|
+
- `effectLedger`: the detached immutable schema-version-1 mirror most recently
|
|
1690
|
+
acknowledged by the current host's atomic ledger channel; a linked workflow
|
|
1691
|
+
runtime carries the complete current-host mirror, while the internal compiled
|
|
1692
|
+
Captain runtime carries the exact empty ledger.
|
|
1342
1693
|
- `roleResumeTokens`: the local-role resume-token projection as a plain object
|
|
1343
1694
|
(§PlaybookPorts contract).
|
|
1344
1695
|
- `sequences`: the live `trace`, `turn`, `judgeCall`, `playerCall`, and
|
|
1345
1696
|
`playbookCall` counters, plus `captainCall` when the runtime supports direct
|
|
1346
1697
|
Captain calls.
|
|
1347
|
-
A direct-Captain-capable runtime shall persist it in every schema-version-
|
|
1698
|
+
A direct-Captain-capable runtime shall persist it in every schema-version-4 export.
|
|
1348
1699
|
- `state`: the current normalized state descriptor.
|
|
1349
1700
|
- `pendingBossQuestions`: the pending Boss question(s) from FSM context as
|
|
1350
1701
|
a list of `{ questionId, asker, question, sourceItem? }`, where `asker` is
|
|
@@ -1366,14 +1717,18 @@ unsafe and returns `undefined`.
|
|
|
1366
1717
|
`restore(session, snapshot)` is an alternative to `init` under the same
|
|
1367
1718
|
lifecycle guards (§Session lifecycle): it shall reject when already
|
|
1368
1719
|
initialized, disposing, or disposed, and shall validate
|
|
1369
|
-
schema version `
|
|
1370
|
-
Runtime snapshot schemas `1` and `2` shall reject before state binding because their token and pending-question fields conflate local roles, concrete players, and Captain identity.
|
|
1720
|
+
schema version `4`, the complete effect-ledger mirror, and that `snapshot.playbookId` equals `session.playbookId` before touching state.
|
|
1721
|
+
Runtime snapshot schemas `1` and `2` shall reject before state binding because their token and pending-question fields conflate local roles, concrete players, and Captain identity; schema `3` shall reject because it cannot prove an effect ledger.
|
|
1371
1722
|
The host supplies the same immutable `PlaybookSession` identity the
|
|
1372
1723
|
snapshot was exported under and recreates the runtime through the same
|
|
1373
1724
|
factory with equivalent options; the runtime does not diff options, and
|
|
1374
1725
|
module identity — that the factory constructing this runtime still
|
|
1375
1726
|
belongs to the snapshot's playbook — is likewise the host's check to
|
|
1376
1727
|
make before calling `restore`.
|
|
1728
|
+
Before actor or source-state restoration, a linked workflow runtime shall require
|
|
1729
|
+
the snapshot ledger to equal the detached synchronous mirror exposed by its
|
|
1730
|
+
current-host capability; the internal Captain runtime shall require its mirror
|
|
1731
|
+
to be empty.
|
|
1377
1732
|
`restore` shall bind the session and its current detached role bindings, restore the local-role token projection, the
|
|
1378
1733
|
sequence counters, and the
|
|
1379
1734
|
prior-state descriptor from the snapshot,
|
|
@@ -1396,6 +1751,110 @@ ownership without a child-host call or duplicate start/finish boundary.
|
|
|
1396
1751
|
A restore failure shall leave the runtime unbound so `dispose` remains
|
|
1397
1752
|
callable and terminal.
|
|
1398
1753
|
|
|
1754
|
+
## Retained-snapshot adoption (optional)
|
|
1755
|
+
|
|
1756
|
+
A linked runtime may implement the optional adoption capability of
|
|
1757
|
+
`@sublang/playbook/runtime` — `adopt(session, snapshot, context)` — as a third
|
|
1758
|
+
initialization path distinct from `init` and same-engagement `restore`.
|
|
1759
|
+
Adoption may bind a retained generation to a fresh valid `PlaybookSession`
|
|
1760
|
+
identity. Every runtime the shared `createXStatePlaybookRuntime` factory
|
|
1761
|
+
constructs implements `adopt`, regardless of whether the artifact supplies
|
|
1762
|
+
retained-generation classification metadata; a bespoke runtime may omit it,
|
|
1763
|
+
and hosts feature-detect the capability by member presence.
|
|
1764
|
+
|
|
1765
|
+
Before actor construction or any player-session-store, port, trace, status,
|
|
1766
|
+
or telemetry effect, `adopt` shall validate and detach the target session, the
|
|
1767
|
+
snapshot, and an exact closed-schema `PlaybookAdoptionContext` whose nonempty
|
|
1768
|
+
`sourceSessionId` names the retained frame's source runtime session, whose
|
|
1769
|
+
nonempty `sourceGenerationId` names the retained stack root's source
|
|
1770
|
+
`rootSessionId`, and whose optional nonempty `targetChildSessionId` is present
|
|
1771
|
+
exactly when the snapshot carries a suspended call. The source session and
|
|
1772
|
+
generation ids shall coincide exactly for a root frame. The target session and
|
|
1773
|
+
root ids shall each differ from their source counterparts, and a supplied
|
|
1774
|
+
target child id shall differ from every source and target identity visible to
|
|
1775
|
+
that frame. Accessors, unknown or missing members, empty identities, and an
|
|
1776
|
+
inconsistent child mapping shall reject during preflight.
|
|
1777
|
+
|
|
1778
|
+
That preflight shall also validate the part of the exact structural envelope
|
|
1779
|
+
visible to the runtime: snapshot schema version `4`, target playbook id, the
|
|
1780
|
+
factory's already-validated artifact contract, and any supplied local-role
|
|
1781
|
+
binding set against the artifact's declared roles. The adopting host
|
|
1782
|
+
owns the working-directory and complete catalog-entry comparison — registry
|
|
1783
|
+
module identity, manifest command, options, and role set — plus every retained
|
|
1784
|
+
frame's artifact-schema comparison, and shall perform them before calling the
|
|
1785
|
+
runtime capability (DR-038 §3).
|
|
1786
|
+
The preflight shall apply the same exact full-mirror rule as restore: a linked
|
|
1787
|
+
workflow target receives a current-host mirror equal to the retained ledger,
|
|
1788
|
+
while the internal Captain target requires the retained ledger to be empty.
|
|
1789
|
+
|
|
1790
|
+
Adoption shall not restore any source counter. The fresh target trace, turn,
|
|
1791
|
+
judge-call, player-call, supported direct-Captain-call, playbook-call, and
|
|
1792
|
+
apply-call counter spaces shall start at zero. Before its session-start trace,
|
|
1793
|
+
a descriptor-free adoption leaves the playbook-call counter at zero. A
|
|
1794
|
+
suspended adoption instead consumes `playbook-1` as the fresh target call id,
|
|
1795
|
+
replaces the descriptor's source child id with `targetChildSessionId`, omits the
|
|
1796
|
+
source `turnId`, and sets the target playbook-call counter to one; it changes no
|
|
1797
|
+
opaque persisted machine value and makes no child-host call.
|
|
1798
|
+
|
|
1799
|
+
After preflight, adoption shall construct the persisted actor and prepare the
|
|
1800
|
+
nested bridge through the same transaction as restore, using the rebased
|
|
1801
|
+
descriptor or an explicit absence. Before actor startup it shall emit exactly
|
|
1802
|
+
one `session.started` as target trace sequence `1`, carrying the adopted
|
|
1803
|
+
top-level `state` and optional `stateId` plus an exact `adoption` object:
|
|
1804
|
+
|
|
1805
|
+
- without a suspended call, `{ sourceSessionId, sourceGenerationId }`;
|
|
1806
|
+
- with a suspended call, `{ sourceSessionId, sourceGenerationId,
|
|
1807
|
+
sourceCallId, sourceChildSessionId, targetCallId: 'playbook-1',
|
|
1808
|
+
targetChildSessionId }`, while the event also carries top-level
|
|
1809
|
+
`callId: 'playbook-1'` and no `turnId`.
|
|
1810
|
+
|
|
1811
|
+
The runtime shall then start the actor with inspection effects suppressed,
|
|
1812
|
+
claim the rebased descriptor, require the reconstructed active normalized
|
|
1813
|
+
state to equal the retained state under that rebase, drain suppressed work,
|
|
1814
|
+
and confirm the bridge as the final fallible step. A preflight mismatch emits
|
|
1815
|
+
nothing. A later state or bridge mismatch makes no child-host call or
|
|
1816
|
+
playbook-call start/finish boundary, rolls provisional ownership back, and,
|
|
1817
|
+
because the target start was attempted, performs failed-start cleanup with one
|
|
1818
|
+
best-effort target `session.disposed`; successful cleanup leaves the runtime
|
|
1819
|
+
reusable. A successful adoption shall close `init`, `restore`, and `adopt`
|
|
1820
|
+
under the ordinary one-start runtime lifecycle. Its immediate export shall
|
|
1821
|
+
carry trace sequence `1`, zero fresh turn, judge, and player counters, zero
|
|
1822
|
+
direct-Captain counter when supported, and playbook-call sequence zero or one
|
|
1823
|
+
according to the suspended shape. Later target turns and calls allocate from
|
|
1824
|
+
those fresh counters rather than continue any source id or sequence. Ordinary
|
|
1825
|
+
same-engagement restore remains trace-silent and preserves its source
|
|
1826
|
+
identities and counters exactly (DR-038 §5).
|
|
1827
|
+
|
|
1828
|
+
Adoption shall not apply the retained snapshot's `roleResumeTokens` through a
|
|
1829
|
+
supplied player-session store's `restore` operation or seed runtime-private
|
|
1830
|
+
continuation from them. For every later local-role invocation, any target
|
|
1831
|
+
session `roleBindings` are the sole source of supplied player and prompt
|
|
1832
|
+
identities, and any supplied player-session store is the sole conversation
|
|
1833
|
+
authority. The runtime shall resolve the current binding and, when a store is
|
|
1834
|
+
supplied, select it at the invocation boundary and pass the exact selected
|
|
1835
|
+
token or `false`. Where
|
|
1836
|
+
the ordinary continuation rules authorize a store mutation, that mutation
|
|
1837
|
+
shall target the same store. It shall never fall back to the retained token
|
|
1838
|
+
projection. A replacement binding whose current selection is `false` therefore
|
|
1839
|
+
starts fresh under its new identities; without a supplied store, the target
|
|
1840
|
+
runtime's private continuation starts empty (DR-038 §4).
|
|
1841
|
+
|
|
1842
|
+
## Retained-generation classification (optional)
|
|
1843
|
+
|
|
1844
|
+
A linked runtime may expose the optional read-only
|
|
1845
|
+
`retainedGenerationMetadata` marker of `@sublang/playbook/runtime` together
|
|
1846
|
+
with the parked-session snapshot pair and the independently feature-detected
|
|
1847
|
+
adoption capability so a Captain can retain its safe pre-terminal generations.
|
|
1848
|
+
Its `unfinishedFinalStateIds` array shall preserve the artifact's link-time
|
|
1849
|
+
declaration exactly, including an explicitly empty set, and shall be immutable
|
|
1850
|
+
and detached from that declaration. Absence means the runtime contributes no
|
|
1851
|
+
retained generation; presence supplies only terminal classification metadata
|
|
1852
|
+
and does not itself supply the adoption operation.
|
|
1853
|
+
Every runtime the shared `createXStatePlaybookRuntime` factory constructs from
|
|
1854
|
+
a supplied `unfinishedFinalStateIds` spec member shall expose the marker; a
|
|
1855
|
+
bespoke runtime opts into classification only by implementing the public member
|
|
1856
|
+
itself.
|
|
1857
|
+
|
|
1399
1858
|
## Control surface (optional)
|
|
1400
1859
|
|
|
1401
1860
|
A linked runtime may implement the optional control-surface capability of
|
|
@@ -1432,6 +1891,12 @@ type PlaybookControlReceipt =
|
|
|
1432
1891
|
// Optional PlaybookRuntime members — both or neither:
|
|
1433
1892
|
describe?(): PlaybookControlView;
|
|
1434
1893
|
apply?(input: { actionId: string; key: string; signal: AbortSignal }): Promise<PlaybookControlReceipt>;
|
|
1894
|
+
|
|
1895
|
+
// Independent optional host-only unresolved-envelope identity seam:
|
|
1896
|
+
unresolvedEffectEnvelopes?(): readonly (
|
|
1897
|
+
| { readonly kind: 'boundary'; readonly boundaryId: string }
|
|
1898
|
+
| { readonly kind: 'logical-operation'; readonly operationId: string }
|
|
1899
|
+
)[];
|
|
1435
1900
|
```
|
|
1436
1901
|
|
|
1437
1902
|
`describe()` shall be side-effect free — it emits no trace, status, or
|
|
@@ -1452,6 +1917,16 @@ identifier for it. A state whose source declares no description carries no
|
|
|
1452
1917
|
`stateDescription`: an id is never promoted into a description, so a host is
|
|
1453
1918
|
never handed an identifier dressed as meaning.
|
|
1454
1919
|
|
|
1920
|
+
At that same safe control-capture point, a schema-3 runtime that retains
|
|
1921
|
+
effect-possible outcome-unresolved work may expose
|
|
1922
|
+
`unresolvedEffectEnvelopes()` so its host can project the authoritative effect
|
|
1923
|
+
ledger. The method shall return only exact nonblank durable boundary or
|
|
1924
|
+
logical-operation identities in envelope order, shall return an empty list
|
|
1925
|
+
when no unresolved envelope remains, and shall expose no receipt, repository
|
|
1926
|
+
observation, semantic evidence, prose, or live authority. It is side-effect
|
|
1927
|
+
free on the same terms as `describe()`, and no returned identity or bounded
|
|
1928
|
+
repository evidence shall enter `PlaybookRunResult`.
|
|
1929
|
+
|
|
1455
1930
|
The view's `context` is an explicit projection the linked runtime **authors**,
|
|
1456
1931
|
never an allow-by-default serialization of the FSM context (PBRT-52).
|
|
1457
1932
|
Only the runtime knows which of its context members are safe and relevant
|
|
@@ -1482,8 +1957,9 @@ default. The rules:
|
|
|
1482
1957
|
Actions derive from the live snapshot, only at the same safe point the
|
|
1483
1958
|
parked-session snapshot uses (actor status `active`, quiescent, no pending
|
|
1484
1959
|
nested call); anywhere else `actions` is empty while the rest of the view
|
|
1485
|
-
still describes the state.
|
|
1486
|
-
|
|
1960
|
+
still describes the state.
|
|
1961
|
+
While effect-possible outcome evidence remains unresolved, the view shall omit its pending Boss questions and state description and shall replace every ordinary action with exactly `reconcile:unresolved-effect` labeled `Retry unresolved effect reconciliation` and `abandon:unresolved-effect` labeled `Abandon unresolved workflow attempt`.
|
|
1962
|
+
Otherwise two ordinary families exist, labeled from source state descriptions:
|
|
1487
1963
|
|
|
1488
1964
|
- **Failure-state retry** — while the singular state id is the recoverable
|
|
1489
1965
|
failure state and the live snapshot accepts the retry event sourced below,
|
|
@@ -1528,8 +2004,8 @@ its key — a later call with that key revalidates afresh, traces its own
|
|
|
1528
2004
|
pair, and may execute once the action is advertised — and a key whose call
|
|
1529
2005
|
threw before reaching acceptance (lifecycle misuse, invalid input, a
|
|
1530
2006
|
pre-acceptance abort, a rejected start-boundary sink) likewise records
|
|
1531
|
-
nothing, so a later call with that key may execute.
|
|
1532
|
-
validated event through the same actor drive as `handleBossInput` — state
|
|
2007
|
+
nothing, so a later call with that key may execute.
|
|
2008
|
+
Executing an ordinary retry or jump sends the validated event through the same actor drive as `handleBossInput` — state
|
|
1533
2009
|
transitions, player/judge boundaries, statuses, and traces flow unchanged —
|
|
1534
2010
|
and settles `executed` with the projected run result, or `failed` with the
|
|
1535
2011
|
normalized error when the run settles in the failure state, aborts, or a
|
|
@@ -1540,6 +2016,11 @@ the paired `apply.started` / `apply.finished` events of §Playbook trace, and
|
|
|
1540
2016
|
`apply` shares the single active-boundary sentinel with `handleBossInput`
|
|
1541
2017
|
and `resumePlaybookCall`.
|
|
1542
2018
|
|
|
2019
|
+
Executing `reconcile:unresolved-effect` shall use only the current host's authoritative effect ledger for any reconciliation refresh and shall start no player.
|
|
2020
|
+
When an open deferred logical operation is checkpoint-restoration eligible, that action shall reacquire its exclusive repository claim and compare the current observation with the saved checkpoint; exact equality shall durably consume eligibility and return to the identical bound wait with its stable question through an ordinary nonterminal run result without a player, judge, or semantic-candidate delivery, while inequality or any other still-unresolved evidence shall return `no-action` and remain unresolved.
|
|
2021
|
+
Executing `abandon:unresolved-effect` shall move no FSM state or start any player, judge, Captain, script, or child call and shall settle `executed` with exactly `{ outcome: 'unresolved-effect', state }`, where `state` is the current normalized nonfinal state.
|
|
2022
|
+
That state-only run-result arm shall carry no `stateDescription`, output, pending call, error, repository receipt, effect ledger, semantic evidence, or other bounded effect fact, and shall claim neither an authored outcome nor workflow completion.
|
|
2023
|
+
|
|
1543
2024
|
Acceptance is also the line past which `apply` does not throw, and
|
|
1544
2025
|
publication — the `apply.finished` emission — is the line past which its
|
|
1545
2026
|
receipt no longer changes. A settlement failure after acceptance but before
|
|
@@ -1694,6 +2175,11 @@ The `playbook.trace` copies are the host-agnostic runtime-boundary record requir
|
|
|
1694
2175
|
## Output
|
|
1695
2176
|
|
|
1696
2177
|
The link compiler emits one TypeScript module per playbook.
|
|
2178
|
+
Every linked artifact shall emit an `unfinishedFinalStateIds` set beside its resumable-state registry as mechanical link-time metadata.
|
|
2179
|
+
The set shall contain exactly the stable ids of root `type: 'final'` states whose terminal outcomes leave the procedure unfinished, and shall be explicitly empty when no terminal outcome does.
|
|
2180
|
+
The linker shall not infer the set from a state description, opaque output, or procedure prose.
|
|
2181
|
+
The linker shall reject a declared id that does not name a root final state, and the shared factory shall independently reject it at construction before runtime effects.
|
|
2182
|
+
For a factory-backed artifact the set is a `spec` member; a bespoke artifact shall retain equivalent linked metadata, and the artifact declaration is not itself the public runtime retention marker or an adoption capability.
|
|
1697
2183
|
For an FSM that declares no `type: 'parallel'` state — necessarily flat
|
|
1698
2184
|
under [gears2fsm.md](gears2fsm.md)'s one-state-per-item mapping — it shall
|
|
1699
2185
|
emit the thin shared-factory module defined below.
|
|
@@ -1703,8 +2189,9 @@ machinery satisfying this document's runtime contract and shall not invoke
|
|
|
1703
2189
|
FSMs under [DR-019](../specs/decisions/019-shared-linked-runtime-factory.md).
|
|
1704
2190
|
The FSM-interpreter machinery — actor wiring, boundary tracing, Boss-event
|
|
1705
2191
|
mapping, adjudication, script execution, nested-playbook bridging, session
|
|
1706
|
-
lifecycle, abort handling, and the optional parked-session snapshot
|
|
1707
|
-
|
|
2192
|
+
lifecycle, abort handling, and the optional parked-session snapshot and
|
|
2193
|
+
retained-snapshot adoption capabilities — is not regenerated for a
|
|
2194
|
+
factory-backed artifact: it ships once
|
|
1708
2195
|
as the shared `createXStatePlaybookRuntime(machine, spec)` factory exported by
|
|
1709
2196
|
`@sublang/playbook/xstate-runtime`, and the emitted module hands its FSM and
|
|
1710
2197
|
a small per-playbook `spec` to that factory. Every behavioral section of
|
|
@@ -1758,9 +2245,13 @@ The thin emitted module:
|
|
|
1758
2245
|
complete `roleStates` status map derived from every FSM state that invokes
|
|
1759
2246
|
the typed `player` actor, with each `role` copied from that state's
|
|
1760
2247
|
source-derived `meta.playbook.role` (an empty map when there is no such
|
|
1761
|
-
state); the
|
|
2248
|
+
state); the exact schema-3 `outcomeAuthority` map derived
|
|
2249
|
+
from every such state's `invoke.input.result` contract and its linked field
|
|
2250
|
+
authorities and repository dispositions (an explicit empty governed map
|
|
2251
|
+
when there is no such state); the
|
|
1762
2252
|
`verbatimPayloadFields` set derived from annotated result fields above; the
|
|
1763
|
-
`
|
|
2253
|
+
explicitly empty or populated `unfinishedFinalStateIds` set declared above;
|
|
2254
|
+
the `controlContextFields` projection of §Control surface; and any
|
|
1764
2255
|
per-playbook strategy override (classifier, prompt composers,
|
|
1765
2256
|
required-field extraction, status formatting) an earlier section of this
|
|
1766
2257
|
definition requires for that playbook.
|
|
@@ -1817,9 +2308,8 @@ The thin emitted module:
|
|
|
1817
2308
|
runtime-owned arm to have lost payload detail under erasure shall report
|
|
1818
2309
|
that gap rather than emit the entry.
|
|
1819
2310
|
- Supplies `spec.compat` with the compatibility values current at link time:
|
|
1820
|
-
`{ artifactSchema, runtimeAbi }`, where `
|
|
1821
|
-
|
|
1822
|
-
`runtimeAbi` is the installed shared engine's `RUNTIME_ABI` self-report.
|
|
2311
|
+
`{ artifactSchema: 3, runtimeAbi }`, where `runtimeAbi` is the installed shared engine's
|
|
2312
|
+
`RUNTIME_ABI` self-report.
|
|
1823
2313
|
The linker shall verify that the installed engine lists the emitted
|
|
1824
2314
|
schema in `SUPPORTED_ARTIFACT_SCHEMAS` and treat its absence as a
|
|
1825
2315
|
link-time error; it shall not stamp a different member (such as the
|
|
@@ -1830,9 +2320,22 @@ The thin emitted module:
|
|
|
1830
2320
|
module and fails construction on a mismatch, so an artifact linked under
|
|
1831
2321
|
one engine cannot run silently skewed under another. Modules emitted
|
|
1832
2322
|
before this contract carry no `compat` member and shall reject before interpretation.
|
|
1833
|
-
- Requires the containing public registry manifest to advertise the
|
|
1834
|
-
|
|
1835
|
-
`
|
|
2323
|
+
- Requires the containing public registry manifest to advertise the identical
|
|
2324
|
+
`artifactSchema` and an exact implementation `runtimeProfile`. A shared
|
|
2325
|
+
factory profile is `{ kind: 'shared-factory', compat }`, where `compat` is
|
|
2326
|
+
the immutable compatibility record captured by that actual factory from
|
|
2327
|
+
its validated `spec.compat`; a bespoke profile is
|
|
2328
|
+
`{ kind: 'bespoke', artifactSchema }`, with schema `3` declared directly by
|
|
2329
|
+
that implementation and no `runtimeAbi` claim. A registry factory accepts configured options and current
|
|
2330
|
+
host capabilities separately and composes the linked runtime's exact
|
|
2331
|
+
`{ configuredOptions, hostCapabilities }` input. The Captain host shall
|
|
2332
|
+
capture the imported manifest fields once, require capabilities for every
|
|
2333
|
+
and only enabled artifact id, validate each capability's artifact, role,
|
|
2334
|
+
cohort, and canonical-worktree authority, and reject a missing, extra,
|
|
2335
|
+
malformed, or mismatched capability before runtime construction.
|
|
2336
|
+
- Default-exports the factory call as `createPlaybookRuntime`, typed as
|
|
2337
|
+
`XStatePlaybookRuntimeFactory<XStatePlaybookRuntimeConstruction<PlaybookRuntimeOptions, HostCapabilities>, 3>`
|
|
2338
|
+
with the artifact's declared live capability type. A registry module loads
|
|
1836
2339
|
dynamically inside the host's caught boundary, so its eager module-scope
|
|
1837
2340
|
factory call fails fast there. The compiled session Captain module is the
|
|
1838
2341
|
exception: the shell and both CLI front ends import it statically, so it
|