@sublang/playbook 8.0.0 → 9.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.
Files changed (30) hide show
  1. package/README.md +3 -3
  2. package/docs/cli.md +15 -15
  3. package/docs/configuration.md +13 -8
  4. package/docs/embedding.md +7 -2
  5. package/package.json +1 -1
  6. package/reference/sdlc/captain.playbook/captain.playbook.js +14 -3
  7. package/reference/sdlc/captain.playbook/captain.playbook.ts +18 -4
  8. package/reference/sdlc/code.playbook/code.fsm.d.ts +4 -1
  9. package/reference/sdlc/code.playbook/code.fsm.js +11 -4
  10. package/reference/sdlc/code.playbook/code.fsm.ts +12 -4
  11. package/reference/sdlc/code.playbook/code.playbook.js +14 -3
  12. package/reference/sdlc/code.playbook/code.playbook.ts +13 -3
  13. package/reference/sdlc/code.playbook/playbook-captain.js +44 -10
  14. package/reference/sdlc/code.playbook/playbook-captain.ts +47 -10
  15. package/reference/sdlc/decide.playbook/decide.fsm.d.ts +1 -1
  16. package/reference/sdlc/decide.playbook/decide.playbook.d.ts +2 -0
  17. package/reference/sdlc/decide.playbook/decide.playbook.js +299 -117
  18. package/reference/sdlc/decide.playbook/decide.playbook.ts +395 -131
  19. package/reference/sdlc/review.playbook/review.playbook.js +14 -3
  20. package/reference/sdlc/review.playbook/review.playbook.ts +13 -3
  21. package/slc/gears2fsm.md +19 -2
  22. package/slc/link.md +184 -42
  23. package/src/runtime.d.ts +1 -0
  24. package/src/runtime.ts +1 -0
  25. package/src/xstate-playbook-runtime.d.ts +13 -3
  26. package/src/xstate-playbook-runtime.js +732 -251
  27. package/src/xstate-playbook-runtime.ts +873 -280
  28. package/src/xstate-runtime.d.ts +17 -7
  29. package/src/xstate-runtime.js +135 -57
  30. package/src/xstate-runtime.ts +243 -84
@@ -561,6 +561,31 @@ function stateDigestLine(
561
561
  ].join('; ');
562
562
  }
563
563
 
564
+ // CAPTAIN-5's mirrored ledger member holds the runtime snapshot's
565
+ // pending-question projection — entries of `{ questionId, asker, question,
566
+ // sourceItem }` — never a raw telemetry payload: the linked runtime's state
567
+ // telemetry carries the singular full-context question, whose extra
568
+ // runtime-internal fields (`resumeStateId`) fail the durable snapshot's
569
+ // leaf-projection equality (CAPTAIN-41) and with it headless settlement.
570
+ function mirroredBossQuestions(value: unknown): unknown {
571
+ if (value === undefined || value === null) return undefined;
572
+ const entries = Array.isArray(value) ? value : [value];
573
+ return entries.map((entry) => {
574
+ if (typeof entry !== 'object' || entry === null) return entry;
575
+ const record = entry as Record<string, unknown>;
576
+ const projected: Record<string, unknown> = {};
577
+ if (record.questionId !== undefined) {
578
+ projected.questionId = record.questionId;
579
+ }
580
+ if (record.asker !== undefined) projected.asker = record.asker;
581
+ if (record.question !== undefined) projected.question = record.question;
582
+ if (record.sourceItem !== undefined) {
583
+ projected.sourceItem = record.sourceItem;
584
+ }
585
+ return projected;
586
+ });
587
+ }
588
+
564
589
  function pendingQuestionLines(pending: unknown): string[] {
565
590
  const list = Array.isArray(pending)
566
591
  ? pending
@@ -2553,8 +2578,9 @@ export function createPlaybookCaptainShell(
2553
2578
  }
2554
2579
 
2555
2580
  if (leafFrame() === frame) {
2556
- pendingBossQuestions =
2557
- record.pendingBossQuestions ?? record.pendingBossQuestion;
2581
+ pendingBossQuestions = mirroredBossQuestions(
2582
+ record.pendingBossQuestions ?? record.pendingBossQuestion,
2583
+ );
2558
2584
  lastError = normalizeErrorCompact(record.lastError);
2559
2585
  if (state.quiescent && state.tags.includes('playbook.parked')) {
2560
2586
  await setMode(
@@ -3518,7 +3544,7 @@ export function createPlaybookCaptainShell(
3518
3544
  // runtime publishes before disposal removes the frame. The opaque run
3519
3545
  // output remains runtime-to-runtime data and never becomes Captain
3520
3546
  // evidence (CAPPLAY-10).
3521
- activeTurn?.settlementFacts.push(rootCompletionFact(frame));
3547
+ activeTurn?.settlementFacts.push(rootCompletionFact(frame, result));
3522
3548
  await runEffect(() => disposeStack('final'));
3523
3549
  }
3524
3550
  return;
@@ -4606,10 +4632,10 @@ export function createPlaybookCaptainShell(
4606
4632
  // The controller port (DR-029): host validation is the sole effector.
4607
4633
  // -------------------------------------------------------------------------
4608
4634
 
4609
- // The leaf's published state description, read from its control view the
4610
- // same way the digest reads it. A leaf without the pair or one whose view
4611
- // cannot be read at this moment publishes none, and the summary then says
4612
- // so instead of falling back to the state id.
4635
+ // The legacy state-description channel, read from the live control view the
4636
+ // same way the digest reads it. DR-037 makes the terminal result authoritative
4637
+ // for completion; this remains only for an older runtime that omits the new
4638
+ // optional member.
4613
4639
  const leafStateDescription = (
4614
4640
  frame: EngagementFrame,
4615
4641
  ): string | undefined => {
@@ -4621,10 +4647,21 @@ export function createPlaybookCaptainShell(
4621
4647
  }
4622
4648
  };
4623
4649
 
4624
- const rootCompletionFact = (frame: EngagementFrame): string => {
4625
- const published = leafStateDescription(frame);
4650
+ const rootCompletionFact = (
4651
+ frame: EngagementFrame,
4652
+ result: Extract<PlaybookRunResult, { outcome: 'terminal' }>,
4653
+ ): string => {
4654
+ const returned =
4655
+ result.stateDescription === undefined
4656
+ ? ''
4657
+ : compactEvidence(result.stateDescription);
4658
+ const legacy = returned === '' ? leafStateDescription(frame) : undefined;
4626
4659
  const description =
4627
- published === undefined ? '' : compactEvidence(published);
4660
+ returned !== ''
4661
+ ? returned
4662
+ : legacy === undefined
4663
+ ? ''
4664
+ : compactEvidence(legacy);
4628
4665
  return description === ''
4629
4666
  ? `${frameLabel(frame)} completed; its runtime published no result description.`
4630
4667
  : `${frameLabel(frame)} completed; its runtime-published result meaning was ${quoteEvidence(description)}.`;
@@ -200,7 +200,7 @@ export declare const decideMachine: import("xstate").StateMachine<DecideContext,
200
200
  } | {
201
201
  type: "validReviewSuccess";
202
202
  params: unknown;
203
- }, never, "done" | "failed" | "awaitBossReply" | "ready" | "commitCoderProposal" | "reviewCommit" | "reportedReviewFailure" | {
203
+ }, never, "done" | "failed" | "awaitBossReply" | "ready" | "reportedReviewFailure" | "commitCoderProposal" | "reviewCommit" | {
204
204
  independentProposals: {
205
205
  coder: "complete" | "working" | "waiting";
206
206
  reviewer: "complete" | "working" | "waiting";
@@ -27,6 +27,7 @@ declare function normalizeErrorFull(err: unknown): {
27
27
  stack?: string;
28
28
  } | undefined;
29
29
  declare function pendingQuestionsFromContext(context: Record<string, unknown>): PendingBossQuestion[];
30
+ declare function pendingQuestionsForState(state: PlaybookState, context: Record<string, unknown>): PendingBossQuestion[];
30
31
  export declare const createPlaybookRuntime: PlaybookRuntimeFactory<PlaybookRuntimeOptions>;
31
32
  export declare const _internal: {
32
33
  composePlayerPrompt: typeof composePlayerPrompt;
@@ -38,6 +39,7 @@ export declare const _internal: {
38
39
  parseAdjudication: typeof parseAdjudication;
39
40
  combineSignals: typeof combineSignals;
40
41
  pendingQuestionsFromContext: typeof pendingQuestionsFromContext;
42
+ pendingQuestionsForState: typeof pendingQuestionsForState;
41
43
  normalizeErrorCompact: typeof normalizeErrorCompact;
42
44
  normalizeErrorFull: typeof normalizeErrorFull;
43
45
  STATE_DESCRIPTIONS: Readonly<Record<string, string>>;