@akagilnc/pi-workflow-roles 0.1.2152 → 0.1.2157

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akagilnc/pi-workflow-roles",
3
- "version": "0.1.2152",
3
+ "version": "0.1.2157",
4
4
  "description": "Soul-bound workflow roles for Pi",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Single generic auto-resume loop for #416 (owner scope = single LLM call).
3
+ * Call-local retries, at most AUTO_RESUME_LIMIT times, in-place (same runId/session).
4
+ * Unifies presentation: intermediate attempts use dummyIo, only final Terminal is presented.
5
+ */
6
+ import { AUTO_RESUME_LIMIT, isSessionPrincipalAvailable, acquireRunWriterLease, RunWriterLeaseHeldError, type RunWriterLease } from "./run-lifecycle.ts";
7
+ import { isLawfulTypedTerminalOutcome, formatTerminalResult, type TerminalResult } from "./terminal.ts";
8
+ import { presentFailureTerminal, presentStructuralRejection } from "./settlement.ts";
9
+ import type { CliIo } from "./cli-io.ts";
10
+
11
+ const dummyIo: CliIo = { stdout: () => {}, stderr: () => {} };
12
+
13
+ export type AutoResumeDispatchResult = {
14
+ exitCode: number;
15
+ terminal?: TerminalResult;
16
+ };
17
+
18
+ export async function runWithAutoResumeLoop<T extends AutoResumeDispatchResult>(options: {
19
+ admitted: { sessionFile: string; runDirectory: string };
20
+ io: CliIo;
21
+ buildInitialArgs: () => string[];
22
+ buildResumeArgs: () => string[];
23
+ dispatch: (extraArgs: string[], lease: RunWriterLease, isFirst: boolean, attemptIo: CliIo) => Promise<T>;
24
+ }): Promise<T> {
25
+ let autoResumeAttempts = 0;
26
+ let isFirst = true;
27
+ let currentExtraArgs = options.buildInitialArgs();
28
+
29
+ while (true) {
30
+ let lease: RunWriterLease;
31
+ try {
32
+ lease = await acquireRunWriterLease(options.admitted.runDirectory);
33
+ } catch (error) {
34
+ if (error instanceof RunWriterLeaseHeldError) {
35
+ presentStructuralRejection(error, options.io);
36
+ return { exitCode: 2 } as T;
37
+ }
38
+ throw error;
39
+ }
40
+
41
+ const result = await options.dispatch(currentExtraArgs, lease, isFirst, dummyIo);
42
+
43
+ const terminal = (result as { terminal?: TerminalResult }).terminal;
44
+ if (terminal !== undefined) {
45
+ (terminal as { autoResumeCount?: number }).autoResumeCount = autoResumeAttempts;
46
+ }
47
+
48
+ const lawful = terminal !== undefined && isLawfulTypedTerminalOutcome(terminal.roleOutcome);
49
+ if (lawful) {
50
+ if (terminal !== undefined) {
51
+ // Present lawful terminal once to real io (dummy was used inside dispatch)
52
+ options.io.stdout(formatTerminalResult(terminal));
53
+ }
54
+ return result;
55
+ }
56
+
57
+ // Deterministic incomplete/audit_incomplete (merger/collector/judge) would duplicate callId bindings on retry and lose settlement
58
+ if (terminal !== undefined && (terminal.roleOutcome.kind === "incomplete" || terminal.roleOutcome.kind === "audit_incomplete")) {
59
+ if (terminal.roleOutcome.kind === "audit_incomplete") {
60
+ options.io.stdout(formatTerminalResult(terminal));
61
+ } else {
62
+ options.io.stdout(formatTerminalResult(terminal));
63
+ }
64
+ return result;
65
+ }
66
+ // Rich auditor retention detail would be lost on retry (stale child binding)
67
+ if (terminal !== undefined && terminal.roleOutcome.kind === "failure") {
68
+ const terminalJson = JSON.stringify(terminal);
69
+ if (terminalJson.includes("retentionFailure") || terminalJson.includes("ComplianceResponseRetentionError")) {
70
+ presentFailureTerminal(terminal, options.io);
71
+ return result;
72
+ }
73
+ }
74
+
75
+ if (autoResumeAttempts >= AUTO_RESUME_LIMIT) {
76
+ if (terminal !== undefined) {
77
+ if (terminal.roleOutcome.kind === "failure" || terminal.roleOutcome.kind === "no_receipt") {
78
+ presentFailureTerminal(terminal, options.io);
79
+ } else {
80
+ options.io.stdout(formatTerminalResult(terminal));
81
+ }
82
+ }
83
+ return result;
84
+ }
85
+ if (!(await isSessionPrincipalAvailable(options.admitted.sessionFile))) {
86
+ if (terminal !== undefined) {
87
+ if (terminal.roleOutcome.kind === "failure" || terminal.roleOutcome.kind === "no_receipt") {
88
+ presentFailureTerminal(terminal, options.io);
89
+ } else {
90
+ options.io.stdout(formatTerminalResult(terminal));
91
+ }
92
+ }
93
+ return result;
94
+ }
95
+
96
+ autoResumeAttempts++;
97
+ currentExtraArgs = options.buildResumeArgs();
98
+ isFirst = false;
99
+ }
100
+ }
@@ -50,6 +50,7 @@ import {
50
50
  type RunWriterLease,
51
51
  type TypedProviderHttpObservation,
52
52
  } from "./run-lifecycle.ts";
53
+ import { runWithAutoResumeLoop } from "./auto-resume.ts";
53
54
  import {
54
55
  classifyPostAdmissionFailure,
55
56
  exitCodeForTerminalOutcome,
@@ -446,17 +447,7 @@ export async function runPublicCoder(
446
447
  }
447
448
 
448
449
  await markRunAdmitted(admitted);
449
-
450
- let lease: RunWriterLease;
451
- try {
452
- lease = await acquireRunWriterLease(admitted.runDirectory);
453
- } catch (error) {
454
- if (error instanceof RunWriterLeaseHeldError) {
455
- presentStructuralRejection(error, io);
456
- return { exitCode: 2 };
457
- }
458
- throw error;
459
- }
450
+ // #416 scope = single LLM call: call-local retry counter, no persistence.
460
451
 
461
452
  let methodProvenance: PackagedMethodSkillProvenance | undefined;
462
453
  if (admitted.phase === "apply") {
@@ -467,7 +458,6 @@ export async function runPublicCoder(
467
458
  );
468
459
  methodProvenance = material.provenance;
469
460
  } catch (error) {
470
- await lease.release();
471
461
  return await presentControlledFailure(
472
462
  admitted,
473
463
  {
@@ -482,24 +472,35 @@ export async function runPublicCoder(
482
472
  }
483
473
  }
484
474
 
485
- const extraArgs = buildCoderActivationExtraArgs(admitted, {
486
- packageRoot: env.packageRoot,
487
- ...(env.model === undefined ? {} : { model: env.model }),
488
- ...(env.engine === undefined ? {} : { engine: env.engine }),
489
- ...(env.extraPiArgs === undefined ? {} : { extraPiArgs: env.extraPiArgs }),
490
- });
491
-
492
- return await dispatchAdmittedCoder({
475
+ return runWithAutoResumeLoop({
493
476
  admitted,
494
- env: {
495
- ...env,
496
- ...(admitted.correlationId === undefined ? {} : { correlationId: admitted.correlationId }),
497
- },
498
477
  io,
499
- extraArgs,
500
- lease,
501
- ...(methodProvenance === undefined ? {} : { methodProvenance }),
502
- ...(env.engine === undefined ? {} : { effectiveEngine: env.engine }),
478
+ buildInitialArgs: () =>
479
+ buildCoderActivationExtraArgs(admitted, {
480
+ packageRoot: env.packageRoot,
481
+ ...(env.model === undefined ? {} : { model: env.model }),
482
+ ...(env.engine === undefined ? {} : { engine: env.engine }),
483
+ ...(env.extraPiArgs === undefined ? {} : { extraPiArgs: env.extraPiArgs }),
484
+ }),
485
+ buildResumeArgs: () =>
486
+ buildCoderResumeActivationExtraArgs(admitted, {
487
+ packageRoot: env.packageRoot,
488
+ ...(env.model === undefined ? {} : { model: env.model }),
489
+ ...(env.extraPiArgs === undefined ? {} : { extraPiArgs: env.extraPiArgs }),
490
+ }),
491
+ dispatch: (extraArgs, lease, isFirst, attemptIo) =>
492
+ dispatchAdmittedCoder({
493
+ admitted,
494
+ env: {
495
+ ...env,
496
+ ...(admitted.correlationId === undefined ? {} : { correlationId: admitted.correlationId }),
497
+ },
498
+ io: attemptIo,
499
+ extraArgs,
500
+ lease,
501
+ ...(methodProvenance === undefined ? {} : { methodProvenance }),
502
+ ...(isFirst && env.engine !== undefined ? { effectiveEngine: env.engine } : {}),
503
+ }),
503
504
  });
504
505
  }
505
506
 
@@ -587,7 +588,7 @@ export async function runPublicCoderResume(
587
588
  ...(env.extraPiArgs === undefined ? {} : { extraPiArgs: env.extraPiArgs }),
588
589
  });
589
590
 
590
- return await dispatchAdmittedCoder({
591
+ const result = await dispatchAdmittedCoder({
591
592
  admitted,
592
593
  env: {
593
594
  ...env,
@@ -598,6 +599,10 @@ export async function runPublicCoderResume(
598
599
  lease,
599
600
  ...(methodProvenance === undefined ? {} : { methodProvenance }),
600
601
  });
602
+ if (result.terminal !== undefined) {
603
+ (result.terminal as { autoResumeCount?: number }).autoResumeCount = 0;
604
+ }
605
+ return result;
601
606
  }
602
607
 
603
608
  // Re-export for tests that assert typed credential failure channel shape.
@@ -52,6 +52,7 @@ import {
52
52
  type RunWriterLease,
53
53
  type TypedProviderHttpObservation,
54
54
  } from "./run-lifecycle.ts";
55
+ import { runWithAutoResumeLoop } from "./auto-resume.ts";
55
56
  import {
56
57
  classifyPostAdmissionFailure,
57
58
  exitCodeForTerminalOutcome,
@@ -474,22 +475,10 @@ export async function runPublicFixer(
474
475
 
475
476
  await markRunAdmitted(admitted);
476
477
 
477
- let lease: RunWriterLease;
478
- try {
479
- lease = await acquireRunWriterLease(admitted.runDirectory);
480
- } catch (error) {
481
- if (error instanceof RunWriterLeaseHeldError) {
482
- presentStructuralRejection(error, io);
483
- return { exitCode: 2 };
484
- }
485
- throw error;
486
- }
487
-
488
478
  let methodMaterial: PackagedMethodSkillMaterial;
489
479
  try {
490
480
  methodMaterial = await loadFixerMethodMaterial(env.packageRoot);
491
481
  } catch (error) {
492
- await lease.release();
493
482
  return await presentControlledFailure(
494
483
  admitted,
495
484
  {
@@ -502,25 +491,35 @@ export async function runPublicFixer(
502
491
  );
503
492
  }
504
493
 
505
- const extraArgs = buildFixerActivationExtraArgs(admitted, {
506
- packageRoot: env.packageRoot,
507
- ...(env.model === undefined ? {} : { model: env.model }),
508
- ...(env.engine === undefined ? {} : { engine: env.engine }),
509
- ...(env.extraPiArgs === undefined ? {} : { extraPiArgs: env.extraPiArgs }),
510
- });
511
-
512
- return await dispatchAdmittedFixer({
494
+ return runWithAutoResumeLoop({
513
495
  admitted,
514
- env: {
515
- ...env,
516
- ...(admitted.correlationId === undefined ? {} : { correlationId: admitted.correlationId }),
517
- },
518
496
  io,
519
- extraArgs,
520
- lease,
521
- methodMaterial,
522
- // #391: only initial Fixer dispatch records mechanical engine provenance.
523
- ...(env.engine === undefined ? {} : { effectiveEngine: env.engine }),
497
+ buildInitialArgs: () =>
498
+ buildFixerActivationExtraArgs(admitted, {
499
+ packageRoot: env.packageRoot,
500
+ ...(env.model === undefined ? {} : { model: env.model }),
501
+ ...(env.engine === undefined ? {} : { engine: env.engine }),
502
+ ...(env.extraPiArgs === undefined ? {} : { extraPiArgs: env.extraPiArgs }),
503
+ }),
504
+ buildResumeArgs: () =>
505
+ buildFixerResumeActivationExtraArgs(admitted, {
506
+ packageRoot: env.packageRoot,
507
+ ...(env.model === undefined ? {} : { model: env.model }),
508
+ ...(env.extraPiArgs === undefined ? {} : { extraPiArgs: env.extraPiArgs }),
509
+ }),
510
+ dispatch: (extraArgs, lease, isFirst, attemptIo) =>
511
+ dispatchAdmittedFixer({
512
+ admitted,
513
+ env: {
514
+ ...env,
515
+ ...(admitted.correlationId === undefined ? {} : { correlationId: admitted.correlationId }),
516
+ },
517
+ io: attemptIo,
518
+ extraArgs,
519
+ lease,
520
+ methodMaterial,
521
+ ...(isFirst && env.engine !== undefined ? { effectiveEngine: env.engine } : {}),
522
+ }),
524
523
  });
525
524
  }
526
525
 
@@ -600,7 +599,7 @@ export async function runPublicFixerResume(
600
599
  ...(env.extraPiArgs === undefined ? {} : { extraPiArgs: env.extraPiArgs }),
601
600
  });
602
601
 
603
- return await dispatchAdmittedFixer({
602
+ const result = await dispatchAdmittedFixer({
604
603
  admitted,
605
604
  env: {
606
605
  ...env,
@@ -611,6 +610,8 @@ export async function runPublicFixerResume(
611
610
  lease,
612
611
  methodMaterial,
613
612
  });
613
+ if (result.terminal !== undefined) (result.terminal as { autoResumeCount?: number }).autoResumeCount = 0;
614
+ return result;
614
615
  }
615
616
 
616
617
  // Re-export for tests that assert typed credential failure channel shape.
@@ -45,6 +45,7 @@ import {
45
45
  RunWriterLeaseHeldError,
46
46
  type RunWriterLease,
47
47
  } from "./run-lifecycle.ts";
48
+ import { runWithAutoResumeLoop } from "./auto-resume.ts";
48
49
  import {
49
50
  classifyPostAdmissionFailure,
50
51
  exitCodeForTerminalOutcome,
@@ -459,35 +460,33 @@ export async function runPublicJudge(
459
460
 
460
461
  await markRunAdmitted(admitted);
461
462
 
462
- let lease: RunWriterLease;
463
- try {
464
- lease = await acquireRunWriterLease(admitted.runDirectory);
465
- } catch (error) {
466
- if (error instanceof RunWriterLeaseHeldError) {
467
- presentStructuralRejection(error, io);
468
- return { exitCode: 2 };
469
- }
470
- throw error;
471
- }
472
-
473
- const extraArgs = buildJudgeActivationExtraArgs(admitted, {
474
- packageRoot: env.packageRoot,
475
- ...(env.model === undefined ? {} : { model: env.model }),
476
- ...(env.engine === undefined ? {} : { engine: env.engine }),
477
- ...(env.extraPiArgs === undefined ? {} : { extraPiArgs: env.extraPiArgs }),
478
- });
479
-
480
- return await dispatchAdmittedJudge({
463
+ return runWithAutoResumeLoop({
481
464
  admitted,
482
- env: {
483
- ...env,
484
- ...(admitted.correlationId === undefined ? {} : { correlationId: admitted.correlationId }),
485
- },
486
465
  io,
487
- extraArgs,
488
- lease,
489
- // #358: only initial Judge dispatch records mechanical engine provenance.
490
- ...(env.engine === undefined ? {} : { effectiveEngine: env.engine }),
466
+ buildInitialArgs: () =>
467
+ buildJudgeActivationExtraArgs(admitted, {
468
+ packageRoot: env.packageRoot,
469
+ ...(env.model === undefined ? {} : { model: env.model }),
470
+ ...(env.engine === undefined ? {} : { engine: env.engine }),
471
+ ...(env.extraPiArgs === undefined ? {} : { extraPiArgs: env.extraPiArgs }),
472
+ }),
473
+ buildResumeArgs: () =>
474
+ buildJudgeResumeActivationExtraArgs(admitted, {
475
+ ...(env.model === undefined ? {} : { model: env.model }),
476
+ ...(env.extraPiArgs === undefined ? {} : { extraPiArgs: env.extraPiArgs }),
477
+ }),
478
+ dispatch: (extraArgs, lease, isFirst, attemptIo) =>
479
+ dispatchAdmittedJudge({
480
+ admitted,
481
+ env: {
482
+ ...env,
483
+ ...(admitted.correlationId === undefined ? {} : { correlationId: admitted.correlationId }),
484
+ },
485
+ io: attemptIo,
486
+ extraArgs,
487
+ lease,
488
+ ...(isFirst && env.engine !== undefined ? { effectiveEngine: env.engine } : {}),
489
+ }),
491
490
  });
492
491
  }
493
492
 
@@ -552,7 +551,7 @@ export async function runPublicResume(
552
551
  ...(env.extraPiArgs === undefined ? {} : { extraPiArgs: env.extraPiArgs }),
553
552
  });
554
553
 
555
- return await dispatchAdmittedJudge({
554
+ const result = await dispatchAdmittedJudge({
556
555
  admitted,
557
556
  env: {
558
557
  ...env,
@@ -562,4 +561,9 @@ export async function runPublicResume(
562
561
  extraArgs,
563
562
  lease,
564
563
  });
564
+ // Manual resume: distinct scope from per-call auto retry; just expose observation.
565
+ if (result.terminal !== undefined) {
566
+ (result.terminal as { autoResumeCount?: number }).autoResumeCount = 0;
567
+ }
568
+ return result;
565
569
  }
@@ -55,6 +55,7 @@ import {
55
55
  type RunWriterLease,
56
56
  type TypedProviderHttpObservation,
57
57
  } from "./run-lifecycle.ts";
58
+ import { runWithAutoResumeLoop } from "./auto-resume.ts";
58
59
  import {
59
60
  classifyPostAdmissionFailure,
60
61
  exitCodeForTerminalOutcome,
@@ -554,22 +555,10 @@ export async function runPublicMerger(
554
555
 
555
556
  await markRunAdmitted(admitted);
556
557
 
557
- let lease: RunWriterLease;
558
- try {
559
- lease = await acquireRunWriterLease(admitted.runDirectory);
560
- } catch (error) {
561
- if (error instanceof RunWriterLeaseHeldError) {
562
- presentStructuralRejection(error, io);
563
- return { exitCode: 2 };
564
- }
565
- throw error;
566
- }
567
-
568
558
  let methodMaterial: PackagedMethodSkillMaterial;
569
559
  try {
570
560
  methodMaterial = await loadMergerMethodMaterial(env.packageRoot);
571
561
  } catch (error) {
572
- await lease.release();
573
562
  return await presentControlledFailure(
574
563
  admitted,
575
564
  {
@@ -583,24 +572,35 @@ export async function runPublicMerger(
583
572
  );
584
573
  }
585
574
 
586
- const extraArgs = buildMergerActivationExtraArgs(admitted, {
587
- packageRoot: env.packageRoot,
588
- ...(env.model === undefined ? {} : { model: env.model }),
589
- ...(env.engine === undefined ? {} : { engine: env.engine }),
590
- ...(env.extraPiArgs === undefined ? {} : { extraPiArgs: env.extraPiArgs }),
591
- });
592
-
593
- return await dispatchAdmittedMerger({
575
+ return runWithAutoResumeLoop({
594
576
  admitted,
595
- env: {
596
- ...env,
597
- ...(admitted.correlationId === undefined ? {} : { correlationId: admitted.correlationId }),
598
- },
599
577
  io,
600
- extraArgs,
601
- lease,
602
- methodMaterial,
603
- ...(env.engine === undefined ? {} : { effectiveEngine: env.engine }),
578
+ buildInitialArgs: () =>
579
+ buildMergerActivationExtraArgs(admitted, {
580
+ packageRoot: env.packageRoot,
581
+ ...(env.model === undefined ? {} : { model: env.model }),
582
+ ...(env.engine === undefined ? {} : { engine: env.engine }),
583
+ ...(env.extraPiArgs === undefined ? {} : { extraPiArgs: env.extraPiArgs }),
584
+ }),
585
+ buildResumeArgs: () =>
586
+ buildMergerResumeActivationExtraArgs(admitted, {
587
+ packageRoot: env.packageRoot,
588
+ ...(env.model === undefined ? {} : { model: env.model }),
589
+ ...(env.extraPiArgs === undefined ? {} : { extraPiArgs: env.extraPiArgs }),
590
+ }),
591
+ dispatch: (extraArgs, lease, isFirst, attemptIo) =>
592
+ dispatchAdmittedMerger({
593
+ admitted,
594
+ env: {
595
+ ...env,
596
+ ...(admitted.correlationId === undefined ? {} : { correlationId: admitted.correlationId }),
597
+ },
598
+ io: attemptIo,
599
+ extraArgs,
600
+ lease,
601
+ methodMaterial,
602
+ ...(isFirst && env.engine !== undefined ? { effectiveEngine: env.engine } : {}),
603
+ }),
604
604
  });
605
605
  }
606
606
 
@@ -681,7 +681,7 @@ export async function runPublicMergerResume(
681
681
  ...(env.extraPiArgs === undefined ? {} : { extraPiArgs: env.extraPiArgs }),
682
682
  });
683
683
 
684
- return await dispatchAdmittedMerger({
684
+ const result = await dispatchAdmittedMerger({
685
685
  admitted,
686
686
  env: {
687
687
  ...env,
@@ -692,6 +692,8 @@ export async function runPublicMergerResume(
692
692
  lease,
693
693
  methodMaterial,
694
694
  });
695
+ if (result.terminal !== undefined) (result.terminal as { autoResumeCount?: number }).autoResumeCount = 0;
696
+ return result;
695
697
  }
696
698
 
697
699
  export type { ExplicitInternalKnownFailure, PackagedMethodSkillProvenance };
@@ -53,6 +53,7 @@ import {
53
53
  type RunWriterLease,
54
54
  type TypedProviderHttpObservation,
55
55
  } from "./run-lifecycle.ts";
56
+ import { runWithAutoResumeLoop } from "./auto-resume.ts";
56
57
  import {
57
58
  classifyPostAdmissionFailure,
58
59
  exitCodeForTerminalOutcome,
@@ -494,22 +495,10 @@ export async function runPublicReviewer(
494
495
 
495
496
  await markRunAdmitted(admitted);
496
497
 
497
- let lease: RunWriterLease;
498
- try {
499
- lease = await acquireRunWriterLease(admitted.runDirectory);
500
- } catch (error) {
501
- if (error instanceof RunWriterLeaseHeldError) {
502
- presentStructuralRejection(error, io);
503
- return { exitCode: 2 };
504
- }
505
- throw error;
506
- }
507
-
508
498
  let methodMaterial: PackagedMethodSkillMaterial;
509
499
  try {
510
500
  methodMaterial = await loadReviewerMethodMaterial(env.packageRoot);
511
501
  } catch (error) {
512
- await lease.release();
513
502
  return await presentControlledFailure(
514
503
  admitted,
515
504
  {
@@ -522,25 +511,35 @@ export async function runPublicReviewer(
522
511
  );
523
512
  }
524
513
 
525
- const extraArgs = buildReviewerActivationExtraArgs(admitted, {
526
- packageRoot: env.packageRoot,
527
- ...(env.model === undefined ? {} : { model: env.model }),
528
- ...(env.engine === undefined ? {} : { engine: env.engine }),
529
- ...(env.extraPiArgs === undefined ? {} : { extraPiArgs: env.extraPiArgs }),
530
- });
531
-
532
- return await dispatchAdmittedReviewer({
514
+ return runWithAutoResumeLoop({
533
515
  admitted,
534
- env: {
535
- ...env,
536
- ...(admitted.correlationId === undefined ? {} : { correlationId: admitted.correlationId }),
537
- },
538
516
  io,
539
- extraArgs,
540
- lease,
541
- methodMaterial,
542
- // #378: only initial Reviewer dispatch records mechanical engine provenance.
543
- ...(env.engine === undefined ? {} : { effectiveEngine: env.engine }),
517
+ buildInitialArgs: () =>
518
+ buildReviewerActivationExtraArgs(admitted, {
519
+ packageRoot: env.packageRoot,
520
+ ...(env.model === undefined ? {} : { model: env.model }),
521
+ ...(env.engine === undefined ? {} : { engine: env.engine }),
522
+ ...(env.extraPiArgs === undefined ? {} : { extraPiArgs: env.extraPiArgs }),
523
+ }),
524
+ buildResumeArgs: () =>
525
+ buildReviewerResumeActivationExtraArgs(admitted, {
526
+ packageRoot: env.packageRoot,
527
+ ...(env.model === undefined ? {} : { model: env.model }),
528
+ ...(env.extraPiArgs === undefined ? {} : { extraPiArgs: env.extraPiArgs }),
529
+ }),
530
+ dispatch: (extraArgs, lease, isFirst, attemptIo) =>
531
+ dispatchAdmittedReviewer({
532
+ admitted,
533
+ env: {
534
+ ...env,
535
+ ...(admitted.correlationId === undefined ? {} : { correlationId: admitted.correlationId }),
536
+ },
537
+ io: attemptIo,
538
+ extraArgs,
539
+ lease,
540
+ methodMaterial,
541
+ ...(isFirst && env.engine !== undefined ? { effectiveEngine: env.engine } : {}),
542
+ }),
544
543
  });
545
544
  }
546
545
 
@@ -620,7 +619,7 @@ export async function runPublicReviewerResume(
620
619
  ...(env.extraPiArgs === undefined ? {} : { extraPiArgs: env.extraPiArgs }),
621
620
  });
622
621
 
623
- return await dispatchAdmittedReviewer({
622
+ const result = await dispatchAdmittedReviewer({
624
623
  admitted,
625
624
  env: {
626
625
  ...env,
@@ -631,6 +630,8 @@ export async function runPublicReviewerResume(
631
630
  lease,
632
631
  methodMaterial,
633
632
  });
633
+ if (result.terminal !== undefined) (result.terminal as { autoResumeCount?: number }).autoResumeCount = 0;
634
+ return result;
634
635
  }
635
636
 
636
637
  export type { ExplicitInternalKnownFailure, PackagedMethodSkillProvenance };