@akagilnc/pi-workflow-roles 0.1.4742 → 0.1.4759

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.
@@ -27781,42 +27781,6 @@ var init_host_transition_prior_native = __esm({
27781
27781
  }
27782
27782
  });
27783
27783
 
27784
- // src/public-cli/public-run-credentials.ts
27785
- function knownFailureForMissingProviderCredential(model, credentials) {
27786
- if (model === void 0 || credentials === void 0) return void 0;
27787
- if (model.provider !== "openai-codex" && model.provider !== "xai") return void 0;
27788
- if (!missingPublicProviderCredential(model.provider, credentials)) {
27789
- return void 0;
27790
- }
27791
- return {
27792
- cause: "provider",
27793
- identity: {
27794
- name: "MissingProviderCredential",
27795
- code: model.provider
27796
- }
27797
- };
27798
- }
27799
- function missingCredentialPreDispatchFailure(model, credentials) {
27800
- const knownFailure = knownFailureForMissingProviderCredential(model, credentials);
27801
- if (knownFailure === void 0) return void 0;
27802
- return {
27803
- timedOut: false,
27804
- code: 1,
27805
- stderr: `Missing credential for provider ${String(knownFailure.identity?.code ?? "unknown")}`,
27806
- knownFailure
27807
- };
27808
- }
27809
- function postRunMissingCredentialFailure(result, model, credentials) {
27810
- if (!(result.timedOut || result.code !== 0)) return void 0;
27811
- return knownFailureForMissingProviderCredential(model, credentials);
27812
- }
27813
- var init_public_run_credentials = __esm({
27814
- "src/public-cli/public-run-credentials.ts"() {
27815
- "use strict";
27816
- init_config2();
27817
- }
27818
- });
27819
-
27820
27784
  // src/public-cli/process-cancel.ts
27821
27785
  var process_cancel_exports = {};
27822
27786
  __export(process_cancel_exports, {
@@ -28344,8 +28308,8 @@ function withOnceSuccessfulBeforeDispatch(adapters) {
28344
28308
  };
28345
28309
  }
28346
28310
  async function recordBestEffortPostDispatchDiagnostic(admitted, env, diagnostic, io) {
28347
- io.stderr(formatCliDiagnostic(diagnostic));
28348
28311
  const payload = { diagnostic, recordedAt: (/* @__PURE__ */ new Date()).toISOString() };
28312
+ let retentionFailure;
28349
28313
  try {
28350
28314
  await env.sessionAppender(
28351
28315
  env.principalAuthority,
@@ -28353,7 +28317,6 @@ async function recordBestEffortPostDispatchDiagnostic(admitted, env, diagnostic,
28353
28317
  POST_ADMISSION_CLEANUP_DIAGNOSTIC_ENTRY_TYPE,
28354
28318
  payload
28355
28319
  );
28356
- return;
28357
28320
  } catch (appendError) {
28358
28321
  try {
28359
28322
  const artifactsDir = await ensureRealArtifactsDirectory(admitted.runDirectory);
@@ -28364,13 +28327,16 @@ async function recordBestEffortPostDispatchDiagnostic(admitted, env, diagnostic,
28364
28327
  { encoding: "utf8", flag: "wx" }
28365
28328
  );
28366
28329
  } catch (artifactError) {
28367
- io.stderr(
28368
- formatCliDiagnostic(
28369
- `post-dispatch diagnostic durable retention failed on both channels (best-effort continue): dossier=${describeErrorIdentity(appendError)}; artifact=${describeErrorIdentity(artifactError)}`
28370
- )
28371
- );
28330
+ retentionFailure = `post-dispatch diagnostic durable retention failed on both channels (best-effort continue): dossier=${describeErrorIdentity(appendError)}; artifact=${describeErrorIdentity(artifactError)}`;
28372
28331
  }
28373
28332
  }
28333
+ try {
28334
+ io.stderr(formatCliDiagnostic(diagnostic));
28335
+ if (retentionFailure !== void 0) {
28336
+ io.stderr(formatCliDiagnostic(retentionFailure));
28337
+ }
28338
+ } catch {
28339
+ }
28374
28340
  }
28375
28341
  async function resolveResumeMethodMaterialAdapters(input) {
28376
28342
  if (input.shouldLoad === false) {
@@ -28533,12 +28499,11 @@ async function dispatchPostAdmissionTurn(input) {
28533
28499
  if (adapters.afterDispatch !== void 0) await adapters.afterDispatch(admitted, lease);
28534
28500
  return result;
28535
28501
  } catch (error) {
28536
- const primaryFailure = result.terminal !== void 0 && !isLawfulTypedTerminalOutcome(result.terminal.roleOutcome);
28537
- if (primaryFailure) {
28502
+ if (result.terminal !== void 0) {
28538
28503
  await recordBestEffortPostDispatchDiagnostic(
28539
28504
  admitted,
28540
28505
  env,
28541
- `afterDispatch failed beside primary terminal (best-effort continue): ${describeErrorIdentity(error)}`,
28506
+ `afterDispatch failed beside host terminal (best-effort continue): ${describeErrorIdentity(error)}`,
28542
28507
  io
28543
28508
  );
28544
28509
  return result;
@@ -28564,23 +28529,6 @@ async function dispatchPostAdmissionTurn(input) {
28564
28529
  }
28565
28530
  };
28566
28531
  try {
28567
- const missingCredential = missingCredentialPreDispatchFailure(
28568
- env.model,
28569
- env.credentials
28570
- );
28571
- if (missingCredential !== void 0) {
28572
- return {
28573
- ...await presentControlledFailure2(
28574
- admitted,
28575
- withEngineDetourInvocationScope(missingCredential, request.invocationScopeId),
28576
- adapters,
28577
- env.principalAuthority,
28578
- io,
28579
- persistRunState
28580
- ),
28581
- ...deferredPersist
28582
- };
28583
- }
28584
28532
  let previousHost;
28585
28533
  const liveHost = env.host;
28586
28534
  const principalCoordinates = admitted.principal === void 0 ? void 0 : env.principalAuthority.decode(admitted.principal);
@@ -28713,19 +28661,14 @@ async function dispatchPostAdmissionTurn(input) {
28713
28661
  try {
28714
28662
  const sessionFile = admitted.principal !== void 0 ? env.principalAuthority.decode(admitted.principal).sessionFile : "";
28715
28663
  const runnerKnownFailure = adapters.resolveRunnerKnownFailure !== void 0 && sessionFile !== "" ? await adapters.resolveRunnerKnownFailure({ result, sessionFile }) : result.knownFailure;
28716
- const credentialFailure = postRunMissingCredentialFailure(
28717
- result,
28718
- env.model,
28719
- env.credentials
28720
- );
28721
28664
  resolution = await resolveAuditedRunnerFailureResolution({
28722
28665
  runner: runnerKnownFailure,
28723
28666
  sessionFile,
28724
- credential: credentialFailure,
28667
+ credential: void 0,
28725
28668
  runDirectory: admitted.runDirectory
28726
28669
  });
28727
28670
  const processCancelName = processCancelSignalName(env.signal);
28728
- const directHostFailureSignal = result.timedOut || result.knownFailure !== void 0 || runnerKnownFailure !== void 0 || credentialFailure !== void 0 || processCancelName !== void 0;
28671
+ const directHostFailureSignal = result.timedOut || result.knownFailure !== void 0 || runnerKnownFailure !== void 0 || processCancelName !== void 0;
28729
28672
  hostSignalFailed = directHostFailureSignal || result.code !== null && result.code !== 0 || resolution.knownFailure !== void 0;
28730
28673
  settled = await adapters.trySettle(admitted, env.principalAuthority, courtScope);
28731
28674
  if (settled !== void 0) {
@@ -28791,25 +28734,11 @@ async function dispatchPostAdmissionTurn(input) {
28791
28734
  try {
28792
28735
  await persistReturnedRunState(admitted, env.principalAuthority, { lawful: true });
28793
28736
  } catch (error) {
28794
- const failed = await settleAfterTurnStarted(
28737
+ await recordBestEffortPostDispatchDiagnostic(
28795
28738
  admitted,
28796
- withEngineDetourInvocationScope({
28797
- timedOut: false,
28798
- code: null,
28799
- stderr: "",
28800
- thrown: error,
28801
- skipRunStateWrite: true
28802
- }, request.invocationScopeId),
28803
- adapters,
28804
- env.principalAuthority,
28805
- io,
28806
- persistRunState
28807
- );
28808
- return await finishAfterTurn(
28809
- withProcessCancelSkipAutoResume(
28810
- { ...failed, turnDispatched: true, ...deferredPersist },
28811
- env.signal
28812
- )
28739
+ env,
28740
+ `run-state persistence failed beside host terminal (best-effort continue): ${describeErrorIdentity(error)}`,
28741
+ io
28813
28742
  );
28814
28743
  }
28815
28744
  }
@@ -28890,25 +28819,11 @@ async function dispatchPostAdmissionTurn(input) {
28890
28819
  try {
28891
28820
  await persistReturnedRunState(admitted, env.principalAuthority, { lawful: true });
28892
28821
  } catch (error) {
28893
- const failed = await settleAfterTurnStarted(
28822
+ await recordBestEffortPostDispatchDiagnostic(
28894
28823
  admitted,
28895
- withEngineDetourInvocationScope({
28896
- timedOut: false,
28897
- code: null,
28898
- stderr: "",
28899
- thrown: error,
28900
- skipRunStateWrite: true
28901
- }, request.invocationScopeId),
28902
- adapters,
28903
- env.principalAuthority,
28904
- io,
28905
- persistRunState
28906
- );
28907
- return await finishAfterTurn(
28908
- withProcessCancelSkipAutoResume(
28909
- { ...failed, turnDispatched: true, ...deferredPersist },
28910
- env.signal
28911
- )
28824
+ env,
28825
+ `run-state persistence failed beside host terminal (best-effort continue): ${describeErrorIdentity(error)}`,
28826
+ io
28912
28827
  );
28913
28828
  }
28914
28829
  }
@@ -28920,14 +28835,16 @@ async function dispatchPostAdmissionTurn(input) {
28920
28835
  ...deferredPersist
28921
28836
  });
28922
28837
  } finally {
28923
- try {
28924
- await lease.release();
28925
- } catch (error) {
28926
- io.stderr(
28927
- formatCliDiagnostic(
28928
- `writer lease release failed unexpectedly (best-effort continue): ${describeErrorIdentity(error)}`
28929
- )
28930
- );
28838
+ if (lease !== void 0) {
28839
+ try {
28840
+ await lease.release();
28841
+ } catch (error) {
28842
+ io.stderr(
28843
+ formatCliDiagnostic(
28844
+ `writer lease release failed unexpectedly (best-effort continue): ${describeErrorIdentity(error)}`
28845
+ )
28846
+ );
28847
+ }
28931
28848
  }
28932
28849
  }
28933
28850
  }
@@ -29242,53 +29159,29 @@ async function runPostAdmissionManualResume(input) {
29242
29159
  } = input;
29243
29160
  let request = input.request;
29244
29161
  const effectiveModel = env.model;
29245
- let lease;
29246
- let staleWriterLeaseReclaimed;
29247
- try {
29248
- lease = await acquireRunWriterLease(admitted.runDirectory, (diagnostic, kind) => {
29249
- if (kind === "stale-reclaimed") staleWriterLeaseReclaimed = true;
29250
- io.stderr(diagnostic);
29251
- });
29252
- } catch (error) {
29253
- if (error instanceof RunWriterLeaseHeldError) {
29254
- io.stderr(formatCliDiagnostic(error.message));
29255
- return {
29256
- exitCode: 1,
29257
- ...staleWriterLeaseReclaimed === true ? { staleWriterLeaseReclaimed: true } : {}
29258
- };
29259
- }
29260
- throw error;
29261
- }
29262
29162
  const invocationScopeId = mintEngineDetourInvocationScope({
29263
29163
  ...effectiveEngine === void 0 ? {} : { effectiveEngine }
29264
29164
  });
29265
- const result = await dispatchAfterWriterLease({
29266
- lease,
29267
- build: async () => {
29268
- if (request === void 0) {
29269
- if (buildRequestAfterLease === void 0) {
29270
- throw new Error(
29271
- "runPostAdmissionManualResume requires request or buildRequestAfterLease"
29272
- );
29273
- }
29274
- request = await buildRequestAfterLease();
29275
- }
29276
- request = withEngineDetourInvocationScope(request, invocationScopeId);
29277
- return request;
29165
+ if (request === void 0) {
29166
+ if (buildRequestAfterLease === void 0) {
29167
+ throw new Error(
29168
+ "runPostAdmissionManualResume requires request or buildRequestAfterLease"
29169
+ );
29170
+ }
29171
+ request = await buildRequestAfterLease();
29172
+ }
29173
+ request = withEngineDetourInvocationScope(request, invocationScopeId);
29174
+ const result = await dispatchPostAdmissionTurn({
29175
+ admitted,
29176
+ env: {
29177
+ ...env,
29178
+ ...effectiveModel === void 0 ? {} : { model: effectiveModel },
29179
+ ...admitted.correlationId === void 0 ? {} : { correlationId: admitted.correlationId }
29278
29180
  },
29279
- dispatch: (turnRequest) => dispatchPostAdmissionTurn({
29280
- admitted,
29281
- env: {
29282
- ...env,
29283
- ...effectiveModel === void 0 ? {} : { model: effectiveModel },
29284
- ...admitted.correlationId === void 0 ? {} : { correlationId: admitted.correlationId }
29285
- },
29286
- io,
29287
- request: turnRequest,
29288
- lease,
29289
- adapters,
29290
- ...effectiveEngine === void 0 ? {} : { effectiveEngine }
29291
- })
29181
+ io,
29182
+ request,
29183
+ adapters,
29184
+ ...effectiveEngine === void 0 ? {} : { effectiveEngine }
29292
29185
  });
29293
29186
  if (result.terminal !== void 0 && isLawfulTypedTerminalOutcome(result.terminal.roleOutcome)) {
29294
29187
  io.stdout(formatTerminalResult(result.terminal));
@@ -29296,10 +29189,7 @@ async function runPostAdmissionManualResume(input) {
29296
29189
  if (result.terminal !== void 0) {
29297
29190
  result.terminal.autoResumeCount = 0;
29298
29191
  }
29299
- return {
29300
- ...result,
29301
- ...staleWriterLeaseReclaimed === true ? { staleWriterLeaseReclaimed: true } : {}
29302
- };
29192
+ return result;
29303
29193
  }
29304
29194
  var StationChildExhaustedError, POST_ADMISSION_CLEANUP_DIAGNOSTIC_ENTRY_TYPE;
29305
29195
  var init_post_admission = __esm({
@@ -29316,7 +29206,6 @@ var init_post_admission = __esm({
29316
29206
  init_case_dossier_delivery();
29317
29207
  init_engine_detour_usage();
29318
29208
  init_host_transition_prior_native();
29319
- init_public_run_credentials();
29320
29209
  init_run_lifecycle();
29321
29210
  init_process_cancel();
29322
29211
  init_activation_ledger_topology();
@@ -35123,8 +35012,7 @@ async function dispatchPublicRoleCommand(env, home, io, parsed, role, parse, run
35123
35012
  function cliResultFromRoleRun(result) {
35124
35013
  return {
35125
35014
  exitCode: result.exitCode,
35126
- ...result.terminal === void 0 ? {} : { terminal: result.terminal },
35127
- ...result.staleWriterLeaseReclaimed === true ? { staleWriterLeaseReclaimed: true } : {}
35015
+ ...result.terminal === void 0 ? {} : { terminal: result.terminal }
35128
35016
  };
35129
35017
  }
35130
35018
  function defaultIo() {
@@ -35,8 +35,7 @@ function isStationChildOfficerDialogue(role, env) {
35
35
  }
36
36
  import { mintEngineDetourInvocationScope, readInvocationSelectedHost, withEngineDetourInvocationScope, } from "../engine-detour-usage.js";
37
37
  import { projectHostTransitionPriorNative } from "../host-transition-prior-native.js";
38
- import { missingCredentialPreDispatchFailure, postRunMissingCredentialFailure, } from "./public-run-credentials.js";
39
- import { acquireRunWriterLease, clearCurrentCourt, clearTypedProviderHttpObservation, describeErrorIdentity, markRunRunning, readCurrentCourt, recordCurrentCourt, renderResumeCommand, RunWriterLeaseHeldError, } from "./run-lifecycle.js";
38
+ import { clearCurrentCourt, clearTypedProviderHttpObservation, describeErrorIdentity, markRunRunning, readCurrentCourt, recordCurrentCourt, renderResumeCommand, } from "./run-lifecycle.js";
40
39
  import { processCancelDiagnostic, processCancelSignalName, } from "./process-cancel.js";
41
40
  import { homeFromRunDirectory } from "../activation-ledger-topology.js";
42
41
  import { attemptProducedFreshSubmission, classifyPostAdmissionFailure, controlledFailureInputFromResolution, exitCodeForTerminalOutcome, explicitInternalKnownFailureClassificationInput, formatCliDiagnostic, formatTerminalResult, inspectJudgeSession, isLawfulTypedTerminalOutcome, presentFailureTerminal, presentStructuralRejection, resolveAuditedRunnerFailureResolution, resolveControlledFailureResumeObservation, settleFailureTerminalResult, settleHostEndedNoReceipt, attachRecordedSubmissions, } from "./settlement.js";
@@ -110,11 +109,10 @@ export const POST_ADMISSION_CLEANUP_DIAGNOSTIC_ENTRY_TYPE = "ak_post_admission_c
110
109
  * redundant second copy (#840 bounce class 1: 同一业务规则只保留一个权威实现).
111
110
  */
112
111
  async function recordBestEffortPostDispatchDiagnostic(admitted, env, diagnostic, io) {
113
- io.stderr(formatCliDiagnostic(diagnostic));
114
112
  const payload = { diagnostic, recordedAt: new Date().toISOString() };
113
+ let retentionFailure;
115
114
  try {
116
115
  await env.sessionAppender(env.principalAuthority, admitted.principal, POST_ADMISSION_CLEANUP_DIAGNOSTIC_ENTRY_TYPE, payload);
117
- return;
118
116
  }
119
117
  catch (appendError) {
120
118
  try {
@@ -122,9 +120,19 @@ async function recordBestEffortPostDispatchDiagnostic(admitted, env, diagnostic,
122
120
  await writeFile(join(artifactsDir, `post-admission-diagnostic-${randomUUID()}.json`), `${JSON.stringify({ version: 1, ...payload }, null, 2)}\n`, { encoding: "utf8", flag: "wx" });
123
121
  }
124
122
  catch (artifactError) {
125
- io.stderr(formatCliDiagnostic(`post-dispatch diagnostic durable retention failed on both channels (best-effort continue): dossier=${describeErrorIdentity(appendError)}; artifact=${describeErrorIdentity(artifactError)}`));
123
+ retentionFailure =
124
+ `post-dispatch diagnostic durable retention failed on both channels (best-effort continue): dossier=${describeErrorIdentity(appendError)}; artifact=${describeErrorIdentity(artifactError)}`;
126
125
  }
127
126
  }
127
+ try {
128
+ io.stderr(formatCliDiagnostic(diagnostic));
129
+ if (retentionFailure !== undefined) {
130
+ io.stderr(formatCliDiagnostic(retentionFailure));
131
+ }
132
+ }
133
+ catch {
134
+ // Presentation is best-effort beside an already-formed host terminal.
135
+ }
128
136
  }
129
137
  /**
130
138
  * Factory-seat resume method-material face (#833): one authority for
@@ -330,10 +338,8 @@ export async function dispatchPostAdmissionTurn(input) {
330
338
  return result;
331
339
  }
332
340
  catch (error) {
333
- const primaryFailure = result.terminal !== undefined
334
- && !isLawfulTypedTerminalOutcome(result.terminal.roleOutcome);
335
- if (primaryFailure) {
336
- await recordBestEffortPostDispatchDiagnostic(admitted, env, `afterDispatch failed beside primary terminal (best-effort continue): ${describeErrorIdentity(error)}`, io);
341
+ if (result.terminal !== undefined) {
342
+ await recordBestEffortPostDispatchDiagnostic(admitted, env, `afterDispatch failed beside host terminal (best-effort continue): ${describeErrorIdentity(error)}`, io);
337
343
  return result;
338
344
  }
339
345
  return {
@@ -350,13 +356,8 @@ export async function dispatchPostAdmissionTurn(input) {
350
356
  }
351
357
  };
352
358
  try {
353
- const missingCredential = missingCredentialPreDispatchFailure(env.model, env.credentials);
354
- if (missingCredential !== undefined) {
355
- return {
356
- ...(await presentControlledFailure(admitted, withEngineDetourInvocationScope(missingCredential, request.invocationScopeId), adapters, env.principalAuthority, io, persistRunState)),
357
- ...deferredPersist,
358
- };
359
- }
359
+ // #987: do not pre-block or classify host dispatch from AK credential
360
+ // catalog facts. Per-invocation runner/host evidence owns provider identity.
360
361
  // #617 DK-4: capture previous invocation host before markRunRunning overwrites it.
361
362
  // Single authority projectHostTransitionPriorNative classifies the prior native volume.
362
363
  // Same-run resume (#637) keeps host identity on the run's invocation page.
@@ -549,11 +550,10 @@ export async function dispatchPostAdmissionTurn(input) {
549
550
  const runnerKnownFailure = adapters.resolveRunnerKnownFailure !== undefined && sessionFile !== ""
550
551
  ? await adapters.resolveRunnerKnownFailure({ result, sessionFile })
551
552
  : result.knownFailure;
552
- const credentialFailure = postRunMissingCredentialFailure(result, env.model, env.credentials);
553
553
  resolution = await resolveAuditedRunnerFailureResolution({
554
554
  runner: runnerKnownFailure,
555
555
  sessionFile,
556
- credential: credentialFailure,
556
+ credential: undefined,
557
557
  runDirectory: admitted.runDirectory,
558
558
  });
559
559
  // A direct, current signal from the host/runner itself (timeout / host
@@ -573,7 +573,6 @@ export async function dispatchPostAdmissionTurn(input) {
573
573
  const directHostFailureSignal = result.timedOut
574
574
  || result.knownFailure !== undefined
575
575
  || runnerKnownFailure !== undefined
576
- || credentialFailure !== undefined
577
576
  || processCancelName !== undefined;
578
577
  hostSignalFailed =
579
578
  directHostFailureSignal
@@ -679,24 +678,7 @@ export async function dispatchPostAdmissionTurn(input) {
679
678
  await persistReturnedRunState(admitted, env.principalAuthority, { lawful: true });
680
679
  }
681
680
  catch (error) {
682
- // #836: `settledOutcome.terminal` already carries recorded
683
- // submissions (attachRecordedSubmissions above). A real run-state
684
- // persistence failure here must surface loudly through the same
685
- // controlled-failure seam every other dispatch-time failure in
686
- // this function uses (ADR 0080: one settlement disposition owner)
687
- // — not escape uncaught to auto-resume's dispatch-retry path,
688
- // whose exhausted-budget terminal carries no recorded submissions
689
- // at all. skipRunStateWrite: the write that just threw is the same
690
- // write presentControlledFailure would otherwise retry — don't
691
- // call a known-failing operation twice.
692
- const failed = await settleAfterTurnStarted(admitted, withEngineDetourInvocationScope({
693
- timedOut: false,
694
- code: null,
695
- stderr: "",
696
- thrown: error,
697
- skipRunStateWrite: true,
698
- }, request.invocationScopeId), adapters, env.principalAuthority, io, persistRunState);
699
- return await finishAfterTurn(withProcessCancelSkipAutoResume({ ...failed, turnDispatched: true, ...deferredPersist }, env.signal));
681
+ await recordBestEffortPostDispatchDiagnostic(admitted, env, `run-state persistence failed beside host terminal (best-effort continue): ${describeErrorIdentity(error)}`, io);
700
682
  }
701
683
  }
702
684
  // Lawful persist + present is the caller's stop seam (auto-resume loop /
@@ -768,19 +750,7 @@ export async function dispatchPostAdmissionTurn(input) {
768
750
  await persistReturnedRunState(admitted, env.principalAuthority, { lawful: true });
769
751
  }
770
752
  catch (error) {
771
- // #836: same run-state persistence hazard as the settled/accepted
772
- // branch above — route through the shared controlled-failure seam so
773
- // the real failure surfaces loudly instead of escaping uncaught to
774
- // auto-resume's dispatch-retry path with no recorded submissions.
775
- // skipRunStateWrite: don't retry the write that just threw.
776
- const failed = await settleAfterTurnStarted(admitted, withEngineDetourInvocationScope({
777
- timedOut: false,
778
- code: null,
779
- stderr: "",
780
- thrown: error,
781
- skipRunStateWrite: true,
782
- }, request.invocationScopeId), adapters, env.principalAuthority, io, persistRunState);
783
- return await finishAfterTurn(withProcessCancelSkipAutoResume({ ...failed, turnDispatched: true, ...deferredPersist }, env.signal));
753
+ await recordBestEffortPostDispatchDiagnostic(admitted, env, `run-state persistence failed beside host terminal (best-effort continue): ${describeErrorIdentity(error)}`, io);
784
754
  }
785
755
  }
786
756
  // #855 cancel re-read lives in finishAfterTurn (before afterDispatch).
@@ -793,17 +763,20 @@ export async function dispatchPostAdmissionTurn(input) {
793
763
  });
794
764
  }
795
765
  finally {
796
- try {
797
- await lease.release();
798
- }
799
- catch (error) {
800
- // lease.release() is documented best-effort and never rejects in the
801
- // production acquireRunWriterLease implementation (createWriterLease
802
- // reports cleanup failures via callback, never throws) — this guard is
803
- // structural only: an uncaught throw from a finally block silently
804
- // replaces whatever the try already returned, including a properly
805
- // tagged turnDispatched:true result (#840 r9 判词 class 1 boundary).
806
- io.stderr(formatCliDiagnostic(`writer lease release failed unexpectedly (best-effort continue): ${describeErrorIdentity(error)}`));
766
+ // Public manual resume (#987) holds no package writer lease.
767
+ if (lease !== undefined) {
768
+ try {
769
+ await lease.release();
770
+ }
771
+ catch (error) {
772
+ // lease.release() is documented best-effort and never rejects in the
773
+ // production acquireRunWriterLease implementation (createWriterLease
774
+ // reports cleanup failures via callback, never throws) — this guard is
775
+ // structural only: an uncaught throw from a finally block silently
776
+ // replaces whatever the try already returned, including a properly
777
+ // tagged turnDispatched:true result (#840 r9 判词 class 1 boundary).
778
+ io.stderr(formatCliDiagnostic(`writer lease release failed unexpectedly (best-effort continue): ${describeErrorIdentity(error)}`));
779
+ }
807
780
  }
808
781
  }
809
782
  }
@@ -951,8 +924,10 @@ export async function prepareSummonsResumeMaterials(runDirectory, summons) {
951
924
  */
952
925
  export async function runPostAdmissionSeatResume(input) {
953
926
  let request = input.request;
954
- // Load once for runDirectory / structural rejection / afterAdmittedLoad;
955
- // court identity is judged only after the writer lease is held (below).
927
+ // Load once for runDirectory / structural rejection / afterAdmittedLoad.
928
+ // Court identity for public manual resume is judged in the turn builder
929
+ // (#987: no package writer-lease gate before host CLI resume). Station-child
930
+ // auto-resume still acquires the shared lease in runWithAutoResumeLoop.
956
931
  let loaded;
957
932
  try {
958
933
  loaded = await input.load(request);
@@ -981,8 +956,9 @@ export async function runPostAdmissionSeatResume(input) {
981
956
  let preparedCleanup;
982
957
  const buildRequestAfterLease = async () => {
983
958
  let openCourtAttemptId;
984
- // Build uses the admitted judged under this lease (rehydrated when open
985
- // court materials ride). Settlement identity stays on the outer admitted.
959
+ // Build uses the admitted for this resume (rehydrated when open court
960
+ // materials ride). Settlement identity stays on the outer admitted.
961
+ // Name kept for station-child callers that still build under lease.
986
962
  let admittedForBuild = loaded.admitted;
987
963
  // Bare resume: open-court pointer is the continue signal (not ledger seal).
988
964
  if (request.summons === undefined) {
@@ -1043,9 +1019,10 @@ export async function runPostAdmissionSeatResume(input) {
1043
1019
  }
1044
1020
  return turnRequest;
1045
1021
  };
1046
- // Court recovery / open under lease, then dispatch.
1022
+ // Court recovery / open, then dispatch. Public manual resume does not take a
1023
+ // package writer lease before the host CLI (#987 / ADR 0080 one-shot).
1047
1024
  // Station-child same-ticket/same-parent resume is call-local auto-resume
1048
- // (#840 / #416). Public `ak-role resume` stays one-shot (ADR 0080).
1025
+ // (#840 / #416) and still acquires the shared lease in its loop.
1049
1026
  // afterAdmittedPrepare runs inside this try so mint failure and cleanup share one finally.
1050
1027
  try {
1051
1028
  if (input.afterAdmittedPrepare !== undefined) {
@@ -1217,74 +1194,41 @@ export async function runPostAdmissionResumable(input) {
1217
1194
  });
1218
1195
  }
1219
1196
  /**
1220
- * Manual resume: lease + dispatch. Pass-through to the host — no sealed-accepted
1221
- * short-circuit (#833 / #416). Court open (summons / message / open court) is
1222
- * built under lease when using buildRequestAfterLease; sole-final stays per-attempt.
1223
- * After-lease build shares dispatchAfterWriterLease with station-child auto-resume.
1197
+ * Manual resume: pass-through to the host CLI resume — no package writer-lease
1198
+ * pre-gate (#987), no sealed-accepted short-circuit (#833 / #416). Court open
1199
+ * (summons / message / open court) is built when using buildRequestAfterLease;
1200
+ * sole-final stays per-attempt. Station-child auto-resume keeps shared lease
1201
+ * acquire in runWithAutoResumeLoop + dispatchAfterWriterLease.
1224
1202
  */
1225
1203
  export async function runPostAdmissionManualResume(input) {
1226
1204
  const { admitted, env, io, adapters, effectiveEngine, buildRequestAfterLease, } = input;
1227
1205
  let request = input.request;
1228
1206
  // #617 DK-3: manual resume writes the live seat/env model (same as new legs).
1229
1207
  const effectiveModel = env.model;
1230
- let lease;
1231
- let staleWriterLeaseReclaimed;
1232
- try {
1233
- lease = await acquireRunWriterLease(admitted.runDirectory, (diagnostic, kind) => {
1234
- // Record the typed fact before the fallible sink: if io.stderr throws
1235
- // (acquire deliberately swallows diagnostic-sink failures), the reclaim
1236
- // still happened and must stay observable.
1237
- if (kind === "stale-reclaimed")
1238
- staleWriterLeaseReclaimed = true;
1239
- io.stderr(diagnostic);
1240
- });
1241
- }
1242
- catch (error) {
1243
- if (error instanceof RunWriterLeaseHeldError) {
1244
- io.stderr(formatCliDiagnostic(error.message));
1245
- // A held rejection after our own reclaim must still carry the fact that
1246
- // this caller reclaimed the stale lock — e.g. another resumer re-locked
1247
- // before our retry create (#629).
1248
- return {
1249
- exitCode: 1,
1250
- ...(staleWriterLeaseReclaimed === true
1251
- ? { staleWriterLeaseReclaimed: true }
1252
- : {}),
1253
- };
1254
- }
1255
- throw error;
1256
- }
1257
1208
  // Explicit public resume is a new counting unit — mint once for this call.
1258
1209
  const invocationScopeId = mintEngineDetourInvocationScope({
1259
1210
  ...(effectiveEngine === undefined ? {} : { effectiveEngine }),
1260
1211
  });
1261
- const result = await dispatchAfterWriterLease({
1262
- lease,
1263
- build: async () => {
1264
- if (request === undefined) {
1265
- if (buildRequestAfterLease === undefined) {
1266
- throw new Error("runPostAdmissionManualResume requires request or buildRequestAfterLease");
1267
- }
1268
- request = await buildRequestAfterLease();
1269
- }
1270
- request = withEngineDetourInvocationScope(request, invocationScopeId);
1271
- return request;
1212
+ if (request === undefined) {
1213
+ if (buildRequestAfterLease === undefined) {
1214
+ throw new Error("runPostAdmissionManualResume requires request or buildRequestAfterLease");
1215
+ }
1216
+ request = await buildRequestAfterLease();
1217
+ }
1218
+ request = withEngineDetourInvocationScope(request, invocationScopeId);
1219
+ const result = await dispatchPostAdmissionTurn({
1220
+ admitted,
1221
+ env: {
1222
+ ...env,
1223
+ ...(effectiveModel === undefined ? {} : { model: effectiveModel }),
1224
+ ...(admitted.correlationId === undefined
1225
+ ? {}
1226
+ : { correlationId: admitted.correlationId }),
1272
1227
  },
1273
- dispatch: (turnRequest) => dispatchPostAdmissionTurn({
1274
- admitted,
1275
- env: {
1276
- ...env,
1277
- ...(effectiveModel === undefined ? {} : { model: effectiveModel }),
1278
- ...(admitted.correlationId === undefined
1279
- ? {}
1280
- : { correlationId: admitted.correlationId }),
1281
- },
1282
- io,
1283
- request: turnRequest,
1284
- lease,
1285
- adapters,
1286
- ...(effectiveEngine === undefined ? {} : { effectiveEngine }),
1287
- }),
1228
+ io,
1229
+ request,
1230
+ adapters,
1231
+ ...(effectiveEngine === undefined ? {} : { effectiveEngine }),
1288
1232
  });
1289
1233
  if (result.terminal !== undefined &&
1290
1234
  isLawfulTypedTerminalOutcome(result.terminal.roleOutcome)) {
@@ -1298,10 +1242,5 @@ export async function runPostAdmissionManualResume(input) {
1298
1242
  if (result.terminal !== undefined) {
1299
1243
  result.terminal.autoResumeCount = 0;
1300
1244
  }
1301
- return {
1302
- ...result,
1303
- ...(staleWriterLeaseReclaimed === true
1304
- ? { staleWriterLeaseReclaimed: true }
1305
- : {}),
1306
- };
1245
+ return result;
1307
1246
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akagilnc/pi-workflow-roles",
3
- "version": "0.1.4742",
3
+ "version": "0.1.4759",
4
4
  "description": "Soul-bound workflow roles for Pi",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",