@akagilnc/pi-workflow-roles 0.1.5015 → 0.1.5037

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.
@@ -15831,7 +15831,7 @@ var init_packaged_role_registry = __esm({
15831
15831
  activationStage: "load-and-install",
15832
15832
  receiptStatusKey: "status",
15833
15833
  // #924: 公用《票面法》三席同装
15834
- sessionMaterials: ["CLAUDE.md", "souls/countersign.md", "souls/ticket-law.md"]
15834
+ sessionMaterials: ["CLAUDE.md", "souls/countersign.md", "souls/ticket-law.md", "resources/countersign-ticket-issue.md"]
15835
15835
  },
15836
15836
  {
15837
15837
  role: "secretariat",
@@ -15839,7 +15839,7 @@ var init_packaged_role_registry = __esm({
15839
15839
  presentSettled: "always",
15840
15840
  summonResume: false,
15841
15841
  admission: "instruction",
15842
- sameParent: "court-diarist",
15842
+ sameParent: "none",
15843
15843
  phases: [null],
15844
15844
  outputTool: SECRETARIAT_OUTPUT_TOOL_NAME,
15845
15845
  settlement: "accepted",
@@ -15855,6 +15855,7 @@ var init_packaged_role_registry = __esm({
15855
15855
  "CLAUDE.md",
15856
15856
  "souls/secretariat.md",
15857
15857
  "souls/ticket-law.md",
15858
+ "resources/secretariat-ticket-identity.md",
15858
15859
  "souls/countersign.md",
15859
15860
  "souls/notary.md"
15860
15861
  ]
@@ -18895,6 +18896,22 @@ async function clearTypedProviderHttpObservation(runDirectory) {
18895
18896
  throw error;
18896
18897
  }
18897
18898
  }
18899
+ async function recordTypedProviderHttpStatus(runDirectory, observation) {
18900
+ if (observation.httpStatus >= 200 && observation.httpStatus < 300) {
18901
+ await clearTypedProviderHttpObservation(runDirectory);
18902
+ return;
18903
+ }
18904
+ const body = {
18905
+ httpStatus: observation.httpStatus,
18906
+ provider: observation.provider
18907
+ };
18908
+ await writeFile2(
18909
+ typedProviderHttpPath(runDirectory),
18910
+ `${JSON.stringify(body)}
18911
+ `,
18912
+ "utf8"
18913
+ );
18914
+ }
18898
18915
  async function readLatestTypedProviderHttpObservation(runDirectory) {
18899
18916
  let text;
18900
18917
  try {
@@ -18927,6 +18944,41 @@ var init_typed_provider_http = __esm({
18927
18944
  });
18928
18945
 
18929
18946
  // src/public-cli/run-lifecycle.ts
18947
+ var run_lifecycle_exports = {};
18948
+ __export(run_lifecycle_exports, {
18949
+ AUTO_RESUME_LIMIT: () => AUTO_RESUME_LIMIT,
18950
+ GATE_DOSSIER_POINTER_PREFIX: () => GATE_DOSSIER_POINTER_PREFIX,
18951
+ RESUME_TRANSPORT_ENVELOPE: () => RESUME_TRANSPORT_ENVELOPE,
18952
+ RunWriterLeaseHeldError: () => RunWriterLeaseHeldError,
18953
+ V1_RESUMABLE_PROVIDERS: () => V1_RESUMABLE_PROVIDERS,
18954
+ acquireRunWriterLease: () => acquireRunWriterLease,
18955
+ autopsyWriterLock: () => autopsyWriterLock,
18956
+ buildAutoResumeContinuationPrompt: () => buildAutoResumeContinuationPrompt,
18957
+ clearCurrentCourt: () => clearCurrentCourt,
18958
+ clearTypedProviderHttpObservation: () => clearTypedProviderHttpObservation,
18959
+ describeErrorIdentity: () => describeErrorIdentity,
18960
+ findLatestRunIdForSeatTicket: () => findLatestRunIdForSeatTicket,
18961
+ findRunDirectoryById: () => findRunDirectoryById,
18962
+ isDurablePrincipalAvailable: () => isDurablePrincipalAvailable,
18963
+ isV1ResumableProvider: () => isV1ResumableProvider,
18964
+ loadResumablePublicRole: () => loadResumablePublicRole,
18965
+ markRunAdmitted: () => markRunAdmitted,
18966
+ markRunResumable: () => markRunResumable,
18967
+ markRunRunning: () => markRunRunning,
18968
+ markRunTerminal: () => markRunTerminal,
18969
+ parentRunPathFromGatePointerInstruction: () => parentRunPathFromGatePointerInstruction,
18970
+ peekRoleRunRole: () => peekRoleRunRole,
18971
+ readCurrentCourt: () => readCurrentCourt,
18972
+ readLatestTypedProviderHttpObservation: () => readLatestTypedProviderHttpObservation,
18973
+ readRoleRunIdentity: () => readRoleRunIdentity,
18974
+ readRoleRunState: () => readRoleRunState,
18975
+ readRunParentPath: () => readRunParentPath,
18976
+ readTypedHttp429Observation: () => readTypedHttp429Observation,
18977
+ recordCurrentCourt: () => recordCurrentCourt,
18978
+ recordTypedProviderHttpStatus: () => recordTypedProviderHttpStatus,
18979
+ renderResumeCommand: () => renderResumeCommand,
18980
+ writeRoleRunState: () => writeRoleRunState
18981
+ });
18930
18982
  import { chmod, lstat as lstat2, open, readdir as readdir4, readFile as readFile12, unlink as unlink3, writeFile as writeFile3 } from "node:fs/promises";
18931
18983
  import { basename as basename6, join as join15 } from "node:path";
18932
18984
  function buildAutoResumeContinuationPrompt(options) {
@@ -19127,6 +19179,11 @@ function materializeRoleRunFromDisk(disk, authority) {
19127
19179
  return void 0;
19128
19180
  }
19129
19181
  }
19182
+ async function readRoleRunState(runDirectory, authority) {
19183
+ const disk = await readRoleRunStateDisk(runDirectory);
19184
+ if (disk === void 0) return void 0;
19185
+ return materializeRoleRunFromDisk(disk, authority)?.run;
19186
+ }
19130
19187
  async function readRoleRunIdentity(runDirectory) {
19131
19188
  const raw = await readRoleRunStateRaw(runDirectory);
19132
19189
  return raw === void 0 ? void 0 : parseRoleRunIdentity(raw, runDirectory);
@@ -19510,7 +19567,7 @@ async function findLatestRunIdForSeatTicket(input) {
19510
19567
  const runId = entry.slice(0, entry.length - suffix.length);
19511
19568
  if (runId.length === 0) continue;
19512
19569
  const parentPath = await readRunParentPath(runDirectory);
19513
- if (parentPath !== input.parentRunPath) continue;
19570
+ if (parentPath !== input.parentRunPath && basename6(parentPath ?? "") !== basename6(input.parentRunPath)) continue;
19514
19571
  if (!await runHasFormedSessionPrincipal(runDirectory)) continue;
19515
19572
  if (best === void 0 || runId > best) best = runId;
19516
19573
  }
@@ -19572,7 +19629,7 @@ function restoredTicketFields(fields) {
19572
19629
  ...fields.courtTicketNumbers === void 0 ? {} : { courtTicketNumbers: fields.courtTicketNumbers }
19573
19630
  };
19574
19631
  }
19575
- async function loadResumableRunRecord(home, runId, authority) {
19632
+ async function loadResumableRunRecord(home, runId, authority, allowUnformedAdmitted = false) {
19576
19633
  const runDirectory = await findRunDirectoryById(home, runId);
19577
19634
  if (runDirectory === void 0) {
19578
19635
  throw new CliUsageError(`unknown role run id: ${runId}`);
@@ -19586,7 +19643,7 @@ async function loadResumableRunRecord(home, runId, authority) {
19586
19643
  throw new CliUsageError(`unknown role run id: ${runId}`);
19587
19644
  }
19588
19645
  const { run, principal } = materialized;
19589
- if (!await isDurablePrincipalAvailable(principal, authority)) {
19646
+ if (!(allowUnformedAdmitted && run.state === "admitted") && !await isDurablePrincipalAvailable(principal, authority)) {
19590
19647
  throw new CliUsageError(
19591
19648
  `role run Pi session principal is unavailable: ${runId}`
19592
19649
  );
@@ -19867,8 +19924,8 @@ async function peekRoleRunRole(home, runId) {
19867
19924
  const run = await readRoleRunIdentity(runDirectory);
19868
19925
  return run?.role;
19869
19926
  }
19870
- async function loadResumablePublicRole(home, runId, authority) {
19871
- const loaded = await loadResumableRunRecord(home, runId, authority);
19927
+ async function loadResumablePublicRole(home, runId, authority, allowUnformedAdmitted = false) {
19928
+ const loaded = await loadResumableRunRecord(home, runId, authority, allowUnformedAdmitted);
19872
19929
  return seatLoadedResult(loaded, admitResumedRole(loaded));
19873
19930
  }
19874
19931
  function admitResumedRole(loaded) {
@@ -21448,12 +21505,7 @@ async function persistAdmittedSourceRunPath(admitted, sourceRunPath) {
21448
21505
  );
21449
21506
  }
21450
21507
  async function bindAdmittedTicketNumber(admitted, ticketNumber) {
21451
- if (admitted.ticketNumber !== void 0) {
21452
- if (admitted.ticketNumber === ticketNumber) return;
21453
- throw new Error(
21454
- `bindAdmittedTicketNumber refuses to replace existing ticket #${admitted.ticketNumber} with #${ticketNumber}`
21455
- );
21456
- }
21508
+ if (admitted.ticketNumber === ticketNumber) return;
21457
21509
  await bindTicketNumberOnRunDirectory(admitted.runDirectory, ticketNumber);
21458
21510
  admitted.ticketNumber = ticketNumber;
21459
21511
  }
@@ -21537,6 +21589,7 @@ async function relocateAdmittedRunToTicket(admitted, authority, heldLease) {
21537
21589
  for (const childRunId of Array.isArray(childRunIds) ? childRunIds : []) {
21538
21590
  if (typeof childRunId !== "string") continue;
21539
21591
  const childDirectory = join17(dirname11(oldRunDirectory), `${childRunId}@diarist`);
21592
+ if (!existsSync5(childDirectory)) continue;
21540
21593
  const childTarget = roleRunPlacement(ledgerHome, {
21541
21594
  bookKey: admitted.bookKey,
21542
21595
  subject: { ticketNumber: admitted.ticketNumber },
@@ -21544,7 +21597,6 @@ async function relocateAdmittedRunToTicket(admitted, authority, heldLease) {
21544
21597
  role: "diarist"
21545
21598
  });
21546
21599
  authority.seal(childTarget);
21547
- if (!existsSync5(childDirectory) && existsSync5(childTarget.runDirectory)) continue;
21548
21600
  await bindTicketNumberOnRunDirectory(childDirectory, admitted.ticketNumber);
21549
21601
  await rehomeUnboundTicketProvenance(childDirectory, admitted.ticketNumber, admitted.projectRoot, homeFromRunDirectory(oldRunDirectory));
21550
21602
  ensureRoleRunDirectory(ledgerHome, dirname11(childTarget.runDirectory));
@@ -21594,25 +21646,8 @@ async function bindTicketNumberOnRunDirectory(runDirectory, ticketNumber) {
21594
21646
  "bindTicketNumberOnRunDirectory"
21595
21647
  );
21596
21648
  const admittedPath = join17(runDirectory, "admitted-request.json");
21597
- const invocationPath = join17(runDirectory, "invocation.json");
21598
21649
  const admitted = JSON.parse(await readFile13(admittedPath, "utf8"));
21599
- const existing = admitted.ticketNumber;
21600
- if (typeof existing === "number") {
21601
- if (existing === ticketNumber) return;
21602
- throw new Error(
21603
- `bindTicketNumberOnRunDirectory refuses to replace existing ticket #${existing} with #${ticketNumber}`
21604
- );
21605
- }
21606
- if (existsSync5(invocationPath)) {
21607
- const invocation = JSON.parse(
21608
- await readFile13(invocationPath, "utf8")
21609
- );
21610
- if (typeof invocation.ticketNumber === "number" && invocation.ticketNumber !== ticketNumber) {
21611
- throw new Error(
21612
- `bindTicketNumberOnRunDirectory refuses to replace invocation ticket #${invocation.ticketNumber} with #${ticketNumber}`
21613
- );
21614
- }
21615
- }
21650
+ if (admitted.ticketNumber === ticketNumber) return;
21616
21651
  await writeFile4(
21617
21652
  admittedPath,
21618
21653
  `${JSON.stringify({ ...admitted, ticketNumber }, null, 2)}
@@ -27121,8 +27156,9 @@ function withOnceSuccessfulBeforeDispatch(adapters) {
27121
27156
  ...adapters,
27122
27157
  beforeDispatch: async (admitted, lease) => {
27123
27158
  if (succeeded) return;
27124
- await hook(admitted, lease);
27159
+ const result = await hook(admitted, lease);
27125
27160
  succeeded = true;
27161
+ return result;
27126
27162
  }
27127
27163
  };
27128
27164
  }
@@ -27384,7 +27420,10 @@ async function dispatchPostAdmissionTurn(input) {
27384
27420
  await clearTypedProviderHttpObservation(admitted.runDirectory);
27385
27421
  if (adapters.beforeDispatch !== void 0) {
27386
27422
  try {
27387
- await adapters.beforeDispatch(admitted, lease);
27423
+ const paused = await adapters.beforeDispatch(admitted, lease);
27424
+ if (paused !== void 0) {
27425
+ return { exitCode: 0, admitted, terminal: paused, skipAutoResume: true };
27426
+ }
27388
27427
  } catch (error) {
27389
27428
  const settled2 = await presentControlledFailure2(
27390
27429
  admitted,
@@ -28438,7 +28477,10 @@ async function summonPublicRole(options) {
28438
28477
  result = stepped.ok;
28439
28478
  }
28440
28479
  const stderr = captured?.stderrText();
28441
- const runDirectory = result.admitted?.runDirectory;
28480
+ const runDirectory = result.terminal !== void 0 && result.terminal.roleOutcome.role !== options.role && typeof result.terminal.runId === "string" ? await (await Promise.resolve().then(() => (init_run_lifecycle(), run_lifecycle_exports))).findRunDirectoryById(
28481
+ home,
28482
+ result.terminal.runId
28483
+ ) : result.admitted?.runDirectory;
28442
28484
  return {
28443
28485
  exitCode: result.exitCode,
28444
28486
  ...result.terminal === void 0 ? {} : { terminal: result.terminal },
@@ -28642,8 +28684,10 @@ async function summonGateOfficer(options) {
28642
28684
  `countersign gate summon requires parent runId from sourceRunDirectory: ${options.sourceRunDirectory}`
28643
28685
  );
28644
28686
  }
28645
- const { readBoardTicketNumber: readBoardTicketNumber2 } = await Promise.resolve().then(() => (init_run_ticket_number(), run_ticket_number_exports));
28687
+ const { isSafePositiveTicketNumber: isSafePositiveTicketNumber2, readBoardTicketNumber: readBoardTicketNumber2 } = await Promise.resolve().then(() => (init_run_ticket_number(), run_ticket_number_exports));
28646
28688
  const parentTicket = await readBoardTicketNumber2(options.sourceRunDirectory);
28689
+ const submittedTicket = options.submission !== null && typeof options.submission === "object" && !Array.isArray(options.submission) ? options.submission.ticketNumber : void 0;
28690
+ const courtTicket = isSafePositiveTicketNumber2(submittedTicket) ? submittedTicket : parentTicket;
28647
28691
  const instruction = options.reask ?? gateReviewInstruction ?? "";
28648
28692
  return summonPublicRole({
28649
28693
  role: options.officer,
@@ -28651,7 +28695,7 @@ async function summonGateOfficer(options) {
28651
28695
  ...common,
28652
28696
  correlationId,
28653
28697
  parentRunPath: options.sourceRunDirectory,
28654
- ...parentTicket === void 0 ? {} : { boundTicketNumber: parentTicket }
28698
+ ...courtTicket === void 0 ? {} : { boundTicketNumber: courtTicket }
28655
28699
  });
28656
28700
  }
28657
28701
  return summonPublicRole({
@@ -28671,11 +28715,6 @@ var init_public_role_summons = __esm({
28671
28715
  });
28672
28716
 
28673
28717
  // src/public-cli/countersign-run.ts
28674
- var countersign_run_exports = {};
28675
- __export(countersign_run_exports, {
28676
- invokeCourtDiarist: () => invokeCourtDiarist,
28677
- runCountersignCourtDiaristStation: () => runCountersignCourtDiaristStation
28678
- });
28679
28718
  function isRecord11(value) {
28680
28719
  return typeof value === "object" && value !== null && !Array.isArray(value);
28681
28720
  }
@@ -28775,7 +28814,8 @@ async function invokeCourtDiarist(input, env, io) {
28775
28814
  kind: "escalate",
28776
28815
  diagnostic: courtDiaristEscalateDiagnostic(roleOutcome, submissions)
28777
28816
  },
28778
- ...result.admitted === void 0 ? {} : { admitted: result.admitted }
28817
+ ...result.admitted === void 0 ? {} : { admitted: result.admitted },
28818
+ ...result.terminal === void 0 ? {} : { terminal: result.terminal }
28779
28819
  };
28780
28820
  }
28781
28821
  if (result.exitCode !== 0) {
@@ -28809,7 +28849,7 @@ async function invokeCourtDiarist(input, env, io) {
28809
28849
  ...result.admitted === void 0 ? {} : { admitted: result.admitted }
28810
28850
  };
28811
28851
  }
28812
- async function runCountersignCourtDiaristStation(admitted, env, io) {
28852
+ async function runCountersignCourtDiaristStation(admitted, env, io, afterTicketNumber) {
28813
28853
  if (env.runCourtDiaristStation !== void 0) {
28814
28854
  await env.runCourtDiaristStation(admitted);
28815
28855
  return;
@@ -28826,7 +28866,8 @@ async function runCountersignCourtDiaristStation(admitted, env, io) {
28826
28866
  } else {
28827
28867
  refreshTickets = [admitted.ticketNumber];
28828
28868
  }
28829
- for (const ticketNumber of refreshTickets) {
28869
+ const completedIndex = afterTicketNumber === void 0 ? -1 : refreshTickets.indexOf(afterTicketNumber);
28870
+ for (const ticketNumber of refreshTickets.slice(completedIndex + 1)) {
28830
28871
  const outcome = await invokeCourtDiarist(
28831
28872
  {
28832
28873
  instruction: `\u6574\u7406 #${ticketNumber} \u7684\u672C\u6848\u4F9D\u636E\u3002`,
@@ -28839,14 +28880,17 @@ async function runCountersignCourtDiaristStation(admitted, env, io) {
28839
28880
  env,
28840
28881
  io
28841
28882
  );
28842
- if (outcome.identity.kind === "escalate") {
28843
- throw new StationChildExhaustedError(outcome.identity.diagnostic);
28844
- }
28845
28883
  if (outcome.failedWithoutEscalate !== void 0) {
28846
28884
  throw new StationChildExhaustedError(
28847
28885
  outcome.failedWithoutEscalate.diagnostic
28848
28886
  );
28849
28887
  }
28888
+ if (outcome.identity.kind === "escalate" && outcome.terminal !== void 0) {
28889
+ return {
28890
+ terminal: outcome.terminal,
28891
+ ...outcome.admitted === void 0 ? {} : { childRunId: outcome.admitted.runId }
28892
+ };
28893
+ }
28850
28894
  }
28851
28895
  }
28852
28896
  var init_countersign_run = __esm({
@@ -28863,6 +28907,7 @@ var init_countersign_run = __esm({
28863
28907
  var instruction_seat_run_exports = {};
28864
28908
  __export(instruction_seat_run_exports, {
28865
28909
  buildInstructionSeatTurnRequest: () => buildInstructionSeatTurnRequest,
28910
+ continueParentAfterChild: () => continueParentAfterChild,
28866
28911
  runPublicInstructionSeat: () => runPublicInstructionSeat,
28867
28912
  runPublicInstructionSeatResume: () => runPublicInstructionSeatResume
28868
28913
  });
@@ -29088,7 +29133,7 @@ async function runCountersignBody(parsed, env, io) {
29088
29133
  projectRoot: resolve10(parsed.project ?? env.cwd),
29089
29134
  role: "countersign",
29090
29135
  parentRunPath: gateParentRunPath,
29091
- ...env.boundTicketNumber === void 0 ? {} : { ticketNumber: env.boundTicketNumber },
29136
+ ...isSafePositiveTicketNumber(env.boundTicketNumber) ? { ticketNumber: env.boundTicketNumber } : {},
29092
29137
  freshSummons: env.freshSummons,
29093
29138
  summons: {
29094
29139
  sourceRunPath: gateParentRunPath,
@@ -29125,14 +29170,16 @@ async function runCountersignBody(parsed, env, io) {
29125
29170
  let typedTicket;
29126
29171
  let typedCourtTicketNumbers;
29127
29172
  let identityDiaristRan = false;
29128
- let unboundDiaristRunId;
29129
- if (env.runCourtDiaristStation === void 0) {
29173
+ let childDiaristRunId;
29174
+ let pausedDiaristTerminal;
29175
+ if (gateParentRunPath === void 0 && env.runCourtDiaristStation === void 0) {
29130
29176
  let outcome;
29131
29177
  try {
29132
29178
  outcome = await invokeCourtDiarist({
29133
29179
  instruction: parsed.instruction ?? "",
29134
29180
  projectRoot: admitted.projectRoot,
29135
29181
  failureLabel: "unbound summons",
29182
+ correlationId: admitted.runId,
29136
29183
  ...env.boundTicketNumber === void 0 ? {} : { boundTicketNumber: env.boundTicketNumber }
29137
29184
  }, env, io);
29138
29185
  } catch (error) {
@@ -29148,15 +29195,16 @@ async function runCountersignBody(parsed, env, io) {
29148
29195
  }, seatAdapters(admitted, env), env.principalAuthority, io);
29149
29196
  }
29150
29197
  identityDiaristRan = true;
29198
+ if (outcome.identity.kind === "escalate") pausedDiaristTerminal = outcome.terminal;
29151
29199
  if (outcome.admitted?.runDirectory.includes(`${sep5}unbound${sep5}runs${sep5}`)) {
29152
- unboundDiaristRunId = outcome.admitted.runId;
29200
+ childDiaristRunId = outcome.admitted.runId;
29153
29201
  }
29154
- if (outcome.identity.kind === "escalate" || outcome.failedWithoutEscalate !== void 0) {
29155
- const diagnostic = outcome.identity.kind === "escalate" ? outcome.identity.diagnostic : outcome.failedWithoutEscalate?.diagnostic ?? "";
29202
+ if (outcome.failedWithoutEscalate !== void 0) {
29203
+ const diagnostic = outcome.failedWithoutEscalate.diagnostic;
29156
29204
  await materializeAdmission(
29157
29205
  isSafePositiveTicketNumber(env.boundTicketNumber) ? env.boundTicketNumber : void 0
29158
29206
  );
29159
- if (unboundDiaristRunId !== void 0) await recordChildDiaristRun(admitted, unboundDiaristRunId);
29207
+ if (childDiaristRunId !== void 0) await recordChildDiaristRun(admitted, childDiaristRunId);
29160
29208
  await markRunAdmitted(admitted, env.principalAuthority);
29161
29209
  return await presentControlledFailure2(admitted, {
29162
29210
  timedOut: false,
@@ -29166,16 +29214,18 @@ async function runCountersignBody(parsed, env, io) {
29166
29214
  }, seatAdapters(admitted, env), env.principalAuthority, io);
29167
29215
  }
29168
29216
  if (outcome.identity.kind === "ticket") {
29169
- typedTicket = isSafePositiveTicketNumber(env.boundTicketNumber) ? env.boundTicketNumber : outcome.identity.ticketNumber;
29217
+ typedTicket = outcome.identity.ticketNumber;
29170
29218
  typedCourtTicketNumbers = outcome.identity.courtTicketNumbers;
29171
- } else if (isSafePositiveTicketNumber(env.boundTicketNumber)) {
29172
- typedTicket = env.boundTicketNumber;
29173
29219
  }
29174
29220
  }
29175
29221
  await materializeAdmission(typedTicket);
29176
29222
  await markRunAdmitted(admitted, env.principalAuthority);
29177
- if (unboundDiaristRunId !== void 0) {
29178
- await recordChildDiaristRun(admitted, unboundDiaristRunId);
29223
+ if (childDiaristRunId !== void 0) {
29224
+ await recordChildDiaristRun(admitted, childDiaristRunId);
29225
+ }
29226
+ if (pausedDiaristTerminal !== void 0) {
29227
+ io.stdout(formatTerminalResult(pausedDiaristTerminal));
29228
+ return { exitCode: 0, admitted, terminal: pausedDiaristTerminal };
29179
29229
  }
29180
29230
  if (gateParentRunPath !== void 0) {
29181
29231
  await persistAdmittedSourceRunPath(admitted, gateParentRunPath);
@@ -29225,7 +29275,11 @@ async function runCountersignBody(parsed, env, io) {
29225
29275
  beforeDispatch: async (admittedSeat, lease) => {
29226
29276
  if (!packagedAdmitsCountersign(admittedSeat.role)) return;
29227
29277
  if (!identityDiaristRan || typedTicket !== void 0) {
29228
- await runCountersignCourtDiaristStation(admittedSeat, env, io);
29278
+ const refresh = await runCountersignCourtDiaristStation(admittedSeat, env, io);
29279
+ if (refresh !== void 0) {
29280
+ io.stdout(formatTerminalResult(refresh.terminal));
29281
+ return refresh.terminal;
29282
+ }
29229
29283
  }
29230
29284
  await relocateAdmittedRunToTicket(admittedSeat, env.principalAuthority, lease);
29231
29285
  Object.assign(turnRequest, buildInstructionSeatTurnRequest(admittedSeat, turnProjection));
@@ -29302,7 +29356,6 @@ async function runPublicInstructionSeat(argv2, env, io, role, parseArgv2) {
29302
29356
  projectRoot,
29303
29357
  role,
29304
29358
  parentRunPath: sourceDirectory,
29305
- ...auditorTicket === void 0 ? {} : { ticketNumber: auditorTicket },
29306
29359
  freshSummons: env.freshSummons,
29307
29360
  summons,
29308
29361
  resume: (runId, materials) => runPublicInstructionSeatResume(
@@ -29328,7 +29381,6 @@ async function runPublicInstructionSeat(argv2, env, io, role, parseArgv2) {
29328
29381
  projectRoot,
29329
29382
  role,
29330
29383
  parentRunPath,
29331
- ...env.boundTicketNumber === void 0 ? {} : { ticketNumber: env.boundTicketNumber },
29332
29384
  freshSummons: env.freshSummons,
29333
29385
  summons,
29334
29386
  resume: (runId, materials) => runPublicInstructionSeatResume(
@@ -29356,7 +29408,6 @@ async function runPublicInstructionSeat(argv2, env, io, role, parseArgv2) {
29356
29408
  throw error;
29357
29409
  }
29358
29410
  const resumeInstruction = env.reviewReask ?? env.gateReviewInstruction;
29359
- const knownTicket = await readBoardTicketNumber(source.runDirectory) ?? env.boundTicketNumber;
29360
29411
  const summons = {
29361
29412
  sourceRunPath: source.runDirectory,
29362
29413
  sourceRun: source,
@@ -29367,7 +29418,6 @@ async function runPublicInstructionSeat(argv2, env, io, role, parseArgv2) {
29367
29418
  projectRoot,
29368
29419
  role,
29369
29420
  parentRunPath: source.runDirectory,
29370
- ...knownTicket === void 0 ? {} : { ticketNumber: knownTicket },
29371
29421
  freshSummons: env.freshSummons,
29372
29422
  summons,
29373
29423
  resume: (runId, materials) => runPublicInstructionSeatResume(
@@ -29404,50 +29454,38 @@ async function runPublicInstructionSeat(argv2, env, io, role, parseArgv2) {
29404
29454
  }
29405
29455
  const runAdmitted = async () => {
29406
29456
  await markRunAdmitted(admitted, env.principalAuthority);
29407
- if (record4.sameParent === "court-diarist") {
29408
- const { invokeCourtDiarist: invokeCourtDiarist2 } = await Promise.resolve().then(() => (init_countersign_run(), countersign_run_exports));
29409
- const outcome = await invokeCourtDiarist2({
29410
- instruction: parsed.instruction ?? "",
29411
- projectRoot: admitted.projectRoot,
29412
- failureLabel: "secretariat unbound summons",
29413
- attachmentPaths: admitted.attachments.map((attachment) => attachment.frozenPath),
29414
- correlationId: admitted.runId
29415
- }, {
29416
- cwd: env.cwd,
29417
- home: env.home,
29418
- agentDir: env.agentDir,
29419
- packageRoot: env.packageRoot,
29420
- ...env.credentials === void 0 ? {} : { credentials: env.credentials },
29421
- ...env.signal === void 0 ? {} : { signal: env.signal },
29422
- ...env.hostAdapters === void 0 ? {} : { hostAdapters: env.hostAdapters }
29423
- }, io);
29457
+ if (role === "secretariat") {
29458
+ let outcome;
29459
+ try {
29460
+ outcome = await invokeCourtDiarist({
29461
+ instruction: parsed.instruction ?? "",
29462
+ projectRoot: admitted.projectRoot,
29463
+ failureLabel: "secretariat unbound summons",
29464
+ attachmentPaths: admitted.attachments.map((attachment) => attachment.frozenPath),
29465
+ correlationId: admitted.runId
29466
+ }, env, io);
29467
+ } catch (error) {
29468
+ return await presentControlledFailure2(admitted, {
29469
+ timedOut: false,
29470
+ code: null,
29471
+ stderr: "",
29472
+ thrown: error
29473
+ }, seatAdapters(admitted, env), env.principalAuthority, io);
29474
+ }
29424
29475
  if (outcome.admitted?.runDirectory.includes(`${sep5}unbound${sep5}runs${sep5}`)) {
29425
29476
  await recordChildDiaristRun(admitted, outcome.admitted.runId);
29426
29477
  }
29427
- if (outcome.identity.kind === "escalate" || outcome.failedWithoutEscalate !== void 0) {
29428
- const diagnostic = outcome.identity.kind === "escalate" ? outcome.identity.diagnostic : outcome.failedWithoutEscalate?.diagnostic ?? "";
29478
+ if (outcome.failedWithoutEscalate !== void 0) {
29429
29479
  return await presentControlledFailure2(admitted, {
29430
29480
  timedOut: false,
29431
29481
  code: null,
29432
29482
  stderr: "",
29433
- thrown: new Error(diagnostic)
29483
+ thrown: new Error(outcome.failedWithoutEscalate.diagnostic)
29434
29484
  }, seatAdapters(admitted, env), env.principalAuthority, io);
29435
29485
  }
29436
- if (outcome.identity.kind === "ticket") {
29437
- try {
29438
- if (outcome.admitted === void 0) throw new Error("court diarist ticket has no admitted run");
29439
- await bindAdmittedTicketNumber(outcome.admitted, outcome.identity.ticketNumber);
29440
- await relocateAdmittedRunToTicket(outcome.admitted, env.principalAuthority);
29441
- await bindAdmittedTicketNumber(admitted, outcome.identity.ticketNumber);
29442
- await relocateAdmittedRunToTicket(admitted, env.principalAuthority);
29443
- } catch (error) {
29444
- return await presentControlledFailure2(admitted, {
29445
- timedOut: false,
29446
- code: null,
29447
- stderr: "",
29448
- thrown: error
29449
- }, seatAdapters(admitted, env), env.principalAuthority, io);
29450
- }
29486
+ if (outcome.identity.kind === "escalate" && outcome.terminal !== void 0) {
29487
+ io.stdout(formatTerminalResult(outcome.terminal));
29488
+ return { exitCode: 0, admitted, terminal: outcome.terminal };
29451
29489
  }
29452
29490
  }
29453
29491
  return dispatchAdmitted(admitted, env, io);
@@ -29511,6 +29549,21 @@ async function runPublicInstructionSeatResume(request, env, io) {
29511
29549
  ...env.engine === void 0 ? {} : { effectiveEngine: env.engine }
29512
29550
  });
29513
29551
  }
29552
+ async function continueParentAfterChild(parentRunId, child, env, io) {
29553
+ const loaded = await loadResumablePublicRole(env.home, parentRunId, env.principalAuthority, true);
29554
+ if (loaded.run.state !== "admitted") {
29555
+ return runPublicInstructionSeatResume({ runId: parentRunId }, env, io);
29556
+ }
29557
+ const admitted = loaded.admitted;
29558
+ if (admitted.role === "countersign" && admitted.ticketNumber !== void 0) {
29559
+ const refresh = await runCountersignCourtDiaristStation(admitted, env, io, child.ticketNumber);
29560
+ if (refresh !== void 0) {
29561
+ io.stdout(formatTerminalResult(refresh.terminal));
29562
+ return { exitCode: 0, admitted, terminal: refresh.terminal };
29563
+ }
29564
+ }
29565
+ return dispatchAdmitted(admitted, env, io);
29566
+ }
29514
29567
  var init_instruction_seat_run = __esm({
29515
29568
  "src/public-cli/instruction-seat-run.ts"() {
29516
29569
  "use strict";
@@ -32470,7 +32523,24 @@ async function runAkRole(argv2, env) {
32470
32523
  }),
32471
32524
  io
32472
32525
  );
32473
- return cliResultFromRoleRun(result);
32526
+ let current = result;
32527
+ while (current.exitCode === 0 && current.admitted?.correlationId !== void 0 && current.terminal?.roleOutcome.kind === "accepted" && !courtDiaristEscalated(current.terminal.roleOutcome)) {
32528
+ const parentRunId = current.admitted.correlationId;
32529
+ const parentRole = await peekRoleRunRole(home, parentRunId);
32530
+ if (parentRole === void 0) break;
32531
+ const parentSeat = resolveEffectiveSeat(config, parentRole, credentials, invocationFromParsed(parsed));
32532
+ const parentEnv = createRoleEnvironment(env, {
32533
+ role: parentRole,
32534
+ home,
32535
+ agentDir,
32536
+ cwd,
32537
+ credentials,
32538
+ seat: parentSeat,
32539
+ config
32540
+ });
32541
+ current = await continueParentAfterChild(parentRunId, current.admitted, parentEnv, io);
32542
+ }
32543
+ return cliResultFromRoleRun(current);
32474
32544
  }
32475
32545
  if (parsed.command !== void 0 && isPublicCliSupportCommand(parsed.command)) {
32476
32546
  throw new CliUsageError(`unhandled support command: ${parsed.command}`);
@@ -32539,6 +32609,7 @@ var init_cli = __esm({
32539
32609
  init_invocation();
32540
32610
  init_option_definitions();
32541
32611
  init_instruction_seat_run();
32612
+ init_countersign_run();
32542
32613
  init_analyst_run();
32543
32614
  init_run_lifecycle();
32544
32615
  init_registry2();
@@ -104,8 +104,9 @@ function withOnceSuccessfulBeforeDispatch(adapters) {
104
104
  beforeDispatch: async (admitted, lease) => {
105
105
  if (succeeded)
106
106
  return;
107
- await hook(admitted, lease);
107
+ const result = await hook(admitted, lease);
108
108
  succeeded = true;
109
+ return result;
109
110
  },
110
111
  };
111
112
  }
@@ -333,9 +334,8 @@ export async function dispatchPostAdmissionTurn(input) {
333
334
  };
334
335
  }
335
336
  try {
336
- // #858: an unbound seat may assert its ticket on the existing receipt.
337
- // Read the original accepted payload; do not rewrite it, infer from prose,
338
- // or reject missing/malformed declarations. An existing binding wins.
337
+ // #858: the first typed assertion files an unbound run. Later receipts
338
+ // remain untouched; this seam does not adjudicate a ticket change.
339
339
  if (admitted.ticketNumber === undefined) {
340
340
  const rows = await readRecordedSubmissionRows(admitted.projectRoot, admitted.runId, { home: homeFromRunDirectory(admitted.runDirectory), sessionParent: join(admitted.runDirectory, "session", "session.jsonl") });
341
341
  const asserted = rows
@@ -429,7 +429,10 @@ export async function dispatchPostAdmissionTurn(input) {
429
429
  // (#840 父子不层叠).
430
430
  if (adapters.beforeDispatch !== undefined) {
431
431
  try {
432
- await adapters.beforeDispatch(admitted, lease);
432
+ const paused = await adapters.beforeDispatch(admitted, lease);
433
+ if (paused !== undefined) {
434
+ return { exitCode: 0, admitted, terminal: paused, skipAutoResume: true };
435
+ }
433
436
  }
434
437
  catch (error) {
435
438
  const settled = (await presentControlledFailure(admitted, withEngineDetourInvocationScope({
@@ -816,11 +816,10 @@ async function runHasFormedSessionPrincipal(runDirectory) {
816
816
  /**
817
817
  * Locate the latest retained run for one seat under a book (#637 / #747).
818
818
  * Same walk surface as findRunDirectoryById (listBookRunDirectories). Match by
819
- * parent run path (officer / gate seats, #747 / #987). A typed ticket number
820
- * does not select a run. runId is UUIDv7 — lexicographic max is latest among
821
- * runs that formed a session principal. No parallel index. Public ticket-number
822
- * selection of a prior run was deleted (#987 Result 7); callers use explicit
823
- * `ak-role resume <runId>`.
819
+ * parent run path (officer / gate seats, #747 / #987), narrowed to a supplied
820
+ * typed ticket for same-ticket gate re-summons. runId is UUIDv7 — lexicographic
821
+ * max is latest among runs that formed a session principal. No parallel index;
822
+ * callers can use explicit `ak-role resume <runId>`.
824
823
  * Only a truly missing book directory means no history; damage/permission errors propagate.
825
824
  */
826
825
  export async function findLatestRunIdForSeatTicket(input) {
@@ -831,11 +830,7 @@ export async function findLatestRunIdForSeatTicket(input) {
831
830
  const bookDir = activationBookDirectory(ledgerHome, input.bookKey);
832
831
  let runDirectories;
833
832
  try {
834
- // A typed ticket narrows the existing walk surface to that ticket's runs;
835
- // same-parent matching below still selects the actual prior leg.
836
- runDirectories = await listBookRunDirectories(input.ticketNumber === undefined
837
- ? bookDir
838
- : join(bookDir, String(input.ticketNumber)));
833
+ runDirectories = await listBookRunDirectories(input.ticketNumber === undefined ? bookDir : join(bookDir, String(input.ticketNumber)));
839
834
  }
840
835
  catch (error) {
841
836
  if (errorCodeOf(error) === "ENOENT")
@@ -852,7 +847,9 @@ export async function findLatestRunIdForSeatTicket(input) {
852
847
  if (runId.length === 0)
853
848
  continue;
854
849
  const parentPath = await readRunParentPath(runDirectory);
855
- if (parentPath !== input.parentRunPath)
850
+ // The parent's ticket can change after this child was admitted. Within one
851
+ // book the run leaf is its stable identity; directory placement is not.
852
+ if (parentPath !== input.parentRunPath && basename(parentPath ?? "") !== basename(input.parentRunPath))
856
853
  continue;
857
854
  // Durable fact: never resume-select a provisional that never formed principal.
858
855
  if (!(await runHasFormedSessionPrincipal(runDirectory)))
@@ -935,7 +932,7 @@ function restoredTicketFields(fields) {
935
932
  : { courtTicketNumbers: fields.courtTicketNumbers }),
936
933
  };
937
934
  }
938
- async function loadResumableRunRecord(home, runId, authority) {
935
+ async function loadResumableRunRecord(home, runId, authority, allowUnformedAdmitted = false) {
939
936
  const runDirectory = await findRunDirectoryById(home, runId);
940
937
  if (runDirectory === undefined) {
941
938
  throw new CliUsageError(`unknown role run id: ${runId}`);
@@ -952,7 +949,7 @@ async function loadResumableRunRecord(home, runId, authority) {
952
949
  throw new CliUsageError(`unknown role run id: ${runId}`);
953
950
  }
954
951
  const { run, principal } = materialized;
955
- if (!(await isDurablePrincipalAvailable(principal, authority))) {
952
+ if (!(allowUnformedAdmitted && run.state === "admitted") && !(await isDurablePrincipalAvailable(principal, authority))) {
956
953
  throw new CliUsageError(`role run Pi session principal is unavailable: ${runId}`);
957
954
  }
958
955
  // Reconstruct admitted identity from durable run record + admitted-request.json.
@@ -1271,8 +1268,8 @@ export async function peekRoleRunRole(home, runId) {
1271
1268
  * selects the existing restore checks. The stored native host session id is
1272
1269
  * read on the public explicit resume seam, not from this load.
1273
1270
  */
1274
- export async function loadResumablePublicRole(home, runId, authority) {
1275
- const loaded = await loadResumableRunRecord(home, runId, authority);
1271
+ export async function loadResumablePublicRole(home, runId, authority, allowUnformedAdmitted = false) {
1272
+ const loaded = await loadResumableRunRecord(home, runId, authority, allowUnformedAdmitted);
1276
1273
  return seatLoadedResult(loaded, admitResumedRole(loaded));
1277
1274
  }
1278
1275
  /**