@akagilnc/pi-workflow-roles 0.1.5614 → 0.1.5650

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 (35) hide show
  1. package/dist/acp-host/production-host.js +960 -465
  2. package/dist/activation-ledger-topology.js +12 -0
  3. package/dist/external-host-turn-loop.js +281 -0
  4. package/dist/headless-host/production-host.js +900 -406
  5. package/dist/migrate-book-topology.js +8 -5
  6. package/dist/pi/role-turn-host.js +33 -3
  7. package/dist/public-cli/instruction-seat-run.js +177 -46
  8. package/dist/public-cli/invocation.js +5 -12
  9. package/dist/public-cli/main.js +541 -165
  10. package/dist/public-cli/post-admission.js +171 -18
  11. package/dist/public-cli/settlement.js +20 -10
  12. package/dist/report-ticket-tool.js +136 -0
  13. package/dist/role-run-placement.js +1 -2
  14. package/dist/role-run-relocation.js +24 -4
  15. package/package.json +1 -1
  16. package/resources/engine-dispatch.md +6 -3
  17. package/resources/engines/claude-code.md +4 -5
  18. package/resources/missing-ticket-reask.md +1 -0
  19. package/src/acp-host/role-turn-host.ts +41 -31
  20. package/src/activation-ledger-topology.ts +16 -0
  21. package/src/external-host-turn-loop.ts +103 -12
  22. package/src/headless-host/role-turn-host.ts +41 -25
  23. package/src/pi/role-turn-host.ts +37 -3
  24. package/src/public-cli/instruction-seat-run.ts +248 -50
  25. package/src/public-cli/invocation.ts +15 -27
  26. package/src/public-cli/post-admission.ts +250 -33
  27. package/src/public-cli/run-lifecycle.ts +5 -5
  28. package/src/public-cli/settlement.ts +38 -11
  29. package/src/public-cli/terminal.ts +6 -0
  30. package/src/report-ticket-tool.ts +176 -0
  31. package/src/role-envelope.ts +28 -3
  32. package/src/role-run-placement.ts +0 -2
  33. package/src/role-run-relocation.ts +45 -4
  34. package/src/role-runtime.ts +6 -0
  35. package/src/worker-submission-gates.ts +26 -3
@@ -168,6 +168,7 @@ __export(activation_ledger_topology_exports, {
168
168
  physicallyContainedIn: () => physicallyContainedIn,
169
169
  resolveActivationLedgerHome: () => resolveActivationLedgerHome,
170
170
  resolveActivationLedgerHomeForPath: () => resolveActivationLedgerHomeForPath,
171
+ tryBookKeyFromAkRolesPath: () => tryBookKeyFromAkRolesPath,
171
172
  tryHomeFromAkRolesPath: () => tryHomeFromAkRolesPath
172
173
  });
173
174
  import {
@@ -189,6 +190,17 @@ function tryHomeFromAkRolesPath(path) {
189
190
  }
190
191
  return path.slice(0, match.index);
191
192
  }
193
+ function tryBookKeyFromAkRolesPath(path) {
194
+ const home = tryHomeFromAkRolesPath(path);
195
+ if (home === void 0 || home.length === 0) return void 0;
196
+ const booksRoot = join2(resolveActivationLedgerHome(home), "books");
197
+ const rel = relative(booksRoot, resolve(path));
198
+ if (rel === "" || rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute(rel)) {
199
+ return void 0;
200
+ }
201
+ const bookKey = rel.split(sep)[0];
202
+ return bookKey === void 0 || bookKey === "" ? void 0 : bookKey;
203
+ }
192
204
  function homeFromRunDirectory(runDirectory) {
193
205
  const home = tryHomeFromAkRolesPath(runDirectory);
194
206
  if (home === void 0 || home.length === 0) {
@@ -1145,8 +1157,7 @@ function roleRunPlacement(ledgerHome, input) {
1145
1157
  return {
1146
1158
  runDirectory,
1147
1159
  sessionDirectory,
1148
- sessionFile: sessionFileIn(sessionDirectory),
1149
- attachmentsDirectory: join3(runDirectory, "attachments")
1160
+ sessionFile: sessionFileIn(sessionDirectory)
1150
1161
  };
1151
1162
  }
1152
1163
  function isUnboundRunDirectory(runDirectory) {
@@ -8136,15 +8147,9 @@ async function relocateAdmittedRunToTicket(admitted, authority, heldLease) {
8136
8147
  }
8137
8148
  await rename2(oldRunDirectory, target.runDirectory);
8138
8149
  heldLease?.relocate(target.runDirectory);
8139
- const admittedRecord = admitted;
8140
- rewriteRunDirectoryPathFields(
8141
- admittedRecord,
8142
- [
8143
- "runDirectory",
8144
- "mergerInputPath"
8145
- ],
8146
- oldRunDirectory,
8147
- target.runDirectory
8150
+ rewriteAdmittedRoleRunPage(
8151
+ admitted,
8152
+ [{ oldRunDirectory, newRunDirectory: target.runDirectory }]
8148
8153
  );
8149
8154
  admitted.principal = principal;
8150
8155
  renderCurrentSync(target.runDirectory);
@@ -8775,7 +8780,6 @@ async function placeRoleAdmission(options) {
8775
8780
  sessionDirectory,
8776
8781
  sessionFile,
8777
8782
  runDirectory,
8778
- attachmentsDirectory,
8779
8783
  ledgerHome,
8780
8784
  bookKey
8781
8785
  } = issueAdmissionPlacement(options.principalAuthority, {
@@ -8796,7 +8800,6 @@ async function placeRoleAdmission(options) {
8796
8800
  sessionDirectory,
8797
8801
  sessionFile,
8798
8802
  attachments,
8799
- attachmentsDirectory,
8800
8803
  ledgerHome,
8801
8804
  ticketFields
8802
8805
  };
@@ -9426,19 +9429,24 @@ function roleOutcomeFromRows(role, rows) {
9426
9429
  if (terminal.length === 0) return void 0;
9427
9430
  const payloads = mine.map((row) => row.accepted);
9428
9431
  const latest = terminal[terminal.length - 1];
9432
+ const submissionToolCallId = typeof latest.toolCallId === "string" && latest.toolCallId.length > 0 ? latest.toolCallId : void 0;
9433
+ const belonging = submissionToolCallId === void 0 ? {} : { submissionToolCallId };
9429
9434
  if (latest.kind === "audit-escalation") {
9430
9435
  return {
9431
- kind: "audit_escalation",
9432
- role,
9433
- status: "audit_escalation",
9434
- payloads,
9435
- ...Object.hasOwn(latest, "auditReceipt") ? { decisiveFacts: {
9436
- auditEscalationReceipt: latest.auditReceipt,
9437
- ...Object.hasOwn(latest, "auditOfficer") ? { auditEscalationOfficer: latest.auditOfficer } : {}
9438
- } } : {}
9436
+ outcome: {
9437
+ kind: "audit_escalation",
9438
+ role,
9439
+ status: "audit_escalation",
9440
+ payloads,
9441
+ ...Object.hasOwn(latest, "auditReceipt") ? { decisiveFacts: {
9442
+ auditEscalationReceipt: latest.auditReceipt,
9443
+ ...Object.hasOwn(latest, "auditOfficer") ? { auditEscalationOfficer: latest.auditOfficer } : {}
9444
+ } } : {}
9445
+ },
9446
+ ...belonging
9439
9447
  };
9440
9448
  }
9441
- return { kind: "accepted", role, payloads };
9449
+ return { outcome: { kind: "accepted", role, payloads }, ...belonging };
9442
9450
  }
9443
9451
  async function sealedLedgerOutcome(admitted, role, scope) {
9444
9452
  const home = sealedLedgerHome(admitted);
@@ -10073,8 +10081,8 @@ function entriesOf(read) {
10073
10081
  }
10074
10082
  async function settleSealedSeat(admitted, authority, scope, options) {
10075
10083
  const coordinates = coordinatesFromAdmitted(authority, admitted);
10076
- const roleOutcome = await sealedLedgerOutcome(admitted, admitted.role, scope);
10077
- if (roleOutcome === void 0 || options.acceptedOnly && roleOutcome.kind !== "accepted") {
10084
+ const settled = await sealedLedgerOutcome(admitted, admitted.role, scope);
10085
+ if (settled === void 0 || options.acceptedOnly && settled.outcome.kind !== "accepted") {
10078
10086
  return void 0;
10079
10087
  }
10080
10088
  const read = await readLawfulSettlementEntries(coordinates.sessionFile);
@@ -10085,15 +10093,23 @@ async function settleSealedSeat(admitted, authority, scope, options) {
10085
10093
  `session read failed beside lawful terminal: ${describeErrorIdentity(read.error)}`
10086
10094
  );
10087
10095
  }
10088
- return finishLawfulSeat(admitted, coordinates, entriesOf(read), roleOutcome, scope);
10096
+ return finishLawfulSeat(
10097
+ admitted,
10098
+ coordinates,
10099
+ entriesOf(read),
10100
+ settled.outcome,
10101
+ scope,
10102
+ settled.submissionToolCallId
10103
+ );
10089
10104
  }
10090
- async function finishLawfulSeat(admitted, coordinates, entries, roleOutcome, scope) {
10105
+ async function finishLawfulSeat(admitted, coordinates, entries, roleOutcome, scope, submissionToolCallId) {
10091
10106
  const artifacts = scope?.previewOnly === true ? [] : await publishDeclaredSeatTerminal(admitted, roleOutcome, coordinates, entries, scope);
10092
10107
  const terminal = await attachEngineDetourToolUsage({
10093
10108
  roleOutcome,
10094
10109
  navigator: extractNavigatorFact(entries),
10095
10110
  artifacts,
10096
- runId: admitted.runId
10111
+ runId: admitted.runId,
10112
+ ...submissionToolCallId === void 0 || submissionToolCallId.length === 0 ? {} : { submissionToolCallId }
10097
10113
  }, coordinates.sessionDirectory, detourUsageContext(admitted, scope));
10098
10114
  return attachRecordedSubmissions(admitted, terminal, scope);
10099
10115
  }
@@ -10445,6 +10461,213 @@ var init_settlement = __esm({
10445
10461
  }
10446
10462
  });
10447
10463
 
10464
+ // src/external-host-turn-loop.ts
10465
+ import { existsSync as existsSync6 } from "node:fs";
10466
+ import { basename as basename9 } from "node:path";
10467
+ async function resolveLiveRunDirectoryPath(recordedPath, home) {
10468
+ if (existsSync6(recordedPath)) return recordedPath;
10469
+ const parsed = parseRunLeaf(basename9(recordedPath));
10470
+ const bookKey = tryBookKeyFromAkRolesPath(recordedPath);
10471
+ if (parsed === void 0 || bookKey === void 0) return void 0;
10472
+ return await findRunDirectoryById(
10473
+ home,
10474
+ parsed.runId,
10475
+ bookKey,
10476
+ parsed.role
10477
+ );
10478
+ }
10479
+ async function syncTurnRequestLivePlacement(request) {
10480
+ const live = await resolveLiveRunDirectoryPath(request.runDirectory, request.home);
10481
+ if (live === void 0) {
10482
+ const parsed = parseRunLeaf(basename9(request.runDirectory));
10483
+ throw new Error(
10484
+ `admitted run ${parsed?.runId ?? "(unparseable)"} missing after host turn; not found under ${request.home}`
10485
+ );
10486
+ }
10487
+ if (live !== request.runDirectory) {
10488
+ projectTurnRequestLiveRunDirectory(
10489
+ request,
10490
+ live
10491
+ );
10492
+ }
10493
+ return live;
10494
+ }
10495
+ async function trySyncTurnRequestLivePlacement(request) {
10496
+ try {
10497
+ return { runDirectory: await syncTurnRequestLivePlacement(request) };
10498
+ } catch (resolveError) {
10499
+ return { resolveError };
10500
+ }
10501
+ }
10502
+ async function retainPackageFaultBesideLivePlacement(request, input) {
10503
+ const live = await trySyncTurnRequestLivePlacement(request);
10504
+ if ("resolveError" in live) {
10505
+ const resolveDiagnostic = `live run path resolve failed beside fault: ${describeErrorIdentity(live.resolveError)}`;
10506
+ try {
10507
+ process.stderr.write(`${input.diagnostic}
10508
+ `);
10509
+ process.stderr.write(`${resolveDiagnostic}
10510
+ `);
10511
+ } catch {
10512
+ }
10513
+ return;
10514
+ }
10515
+ await retainPackageFault({
10516
+ runDirectory: live.runDirectory,
10517
+ diagnostic: input.diagnostic,
10518
+ ...Object.hasOwn(input, "error") ? { error: input.error } : {}
10519
+ });
10520
+ }
10521
+ async function recordTurnDelivery(runDirectory, delivered, source) {
10522
+ try {
10523
+ reportRunRecord(runDirectory, "turn-delivery", {
10524
+ systemPrompt: delivered.systemPrompt,
10525
+ ...delivered.outputSchema === void 0 ? {} : { outputSchema: delivered.outputSchema }
10526
+ }, source);
10527
+ } catch (error) {
10528
+ await retainPackageFault({
10529
+ runDirectory,
10530
+ diagnostic: `turn delivery record failed beside host start: ${describeErrorIdentity(error)}`,
10531
+ error
10532
+ });
10533
+ }
10534
+ }
10535
+ function mergeRoleTurnAbortSignals(prepared, request) {
10536
+ if (request === void 0) return prepared;
10537
+ if (prepared === void 0) return request;
10538
+ return AbortSignal.any([prepared, request]);
10539
+ }
10540
+ function isHostAbortedError(error) {
10541
+ return typeof error === "object" && error !== null && error.code === "host-aborted";
10542
+ }
10543
+ function hostAbortedError(message = "host aborted") {
10544
+ return Object.assign(new Error(message), { code: "host-aborted" });
10545
+ }
10546
+ function externalHostFailure(cause, name, code, details, diagnostic) {
10547
+ return asFailure({
10548
+ cause,
10549
+ identity: { name, code },
10550
+ ...diagnostic === void 0 ? {} : { diagnostic },
10551
+ ...details === void 0 ? {} : { details }
10552
+ });
10553
+ }
10554
+ function asFailure(knownFailure, stderr = "") {
10555
+ return { code: null, stderr, timedOut: false, knownFailure };
10556
+ }
10557
+ async function settleHostAborted(prepared, sessionId) {
10558
+ const closure = await prepared.closeRound();
10559
+ if ("failure" in closure) return asFailure(closure.failure);
10560
+ return asFailure({
10561
+ cause: "session",
10562
+ identity: { name: "HostAborted", code: "host-aborted" },
10563
+ ...sessionId === void 0 ? {} : { details: { sessionId } }
10564
+ });
10565
+ }
10566
+ async function driveExternalRoleTurnRounds(prepared, request, driver) {
10567
+ let prompt = prepared.prompt;
10568
+ const abortSignal = mergeRoleTurnAbortSignals(prepared.abortSignal, request.signal);
10569
+ let result = { code: 0, stderr: "", timedOut: false };
10570
+ const countedReaskLimit = deliveryLimitFromConfig(request.deliveryRequestLimit);
10571
+ const exemptReminders = /* @__PURE__ */ new Set();
10572
+ let countedReasks = 0;
10573
+ for (let attempt = 0; ; attempt += 1) {
10574
+ if (abortSignal?.aborted) return settleHostAborted(prepared, driver.currentSessionId());
10575
+ let round;
10576
+ try {
10577
+ round = await driver.runRound({ prompt, abortSignal, attempt });
10578
+ } catch (error) {
10579
+ if (isHostAbortedError(error)) return settleHostAborted(prepared, driver.currentSessionId());
10580
+ throw error;
10581
+ }
10582
+ if (round.status === "terminal") return round.result;
10583
+ result = {
10584
+ code: round.code !== void 0 ? round.code : 0,
10585
+ stderr: round.stderr ?? "",
10586
+ timedOut: round.timedOut === true,
10587
+ ...round.signal === void 0 ? {} : { signal: round.signal }
10588
+ };
10589
+ let closure;
10590
+ try {
10591
+ closure = await prepared.closeRound();
10592
+ } catch (error) {
10593
+ await retainPackageFaultBesideLivePlacement(request, {
10594
+ diagnostic: `round closure failed beside host terminal: ${describeErrorIdentity(error)}`,
10595
+ error
10596
+ });
10597
+ return result.code === 0 && !result.timedOut && result.signal === void 0 ? { ...result, knownFailure: projectThrownFailureLeaf(error) } : result;
10598
+ }
10599
+ if (closure.accepted) {
10600
+ try {
10601
+ await driver.afterAccepted?.();
10602
+ } catch (error) {
10603
+ await retainPackageFaultBesideLivePlacement(request, {
10604
+ diagnostic: `post-acceptance close failed beside host terminal: ${describeErrorIdentity(error)}`,
10605
+ error
10606
+ });
10607
+ }
10608
+ return result;
10609
+ }
10610
+ if ("failure" in closure) {
10611
+ await retainPackageFaultBesideLivePlacement(request, {
10612
+ diagnostic: `round closure failed beside host terminal: ${JSON.stringify(closure.failure)}`
10613
+ });
10614
+ return result.code === 0 && !result.timedOut && result.signal === void 0 ? { ...result, knownFailure: closure.failure } : result;
10615
+ }
10616
+ if (result.code !== 0 || result.signal !== void 0 || result.timedOut) return result;
10617
+ const reminderCode = closure.retry.code;
10618
+ const exempt = isOneShotWorkerReminderCode(reminderCode) && !exemptReminders.has(reminderCode);
10619
+ if (exempt) exemptReminders.add(reminderCode);
10620
+ else {
10621
+ countedReasks += 1;
10622
+ if (countedReasks > countedReaskLimit) {
10623
+ await retainPackageFaultBesideLivePlacement(request, {
10624
+ diagnostic: `${driver.roundLimitName}: round-retry-limit`
10625
+ });
10626
+ return result;
10627
+ }
10628
+ }
10629
+ prompt = closure.retry.message;
10630
+ driver.afterRetry?.();
10631
+ }
10632
+ }
10633
+ async function disposeExternalRoleTurn(prepared, request, outcome) {
10634
+ try {
10635
+ await prepared.dispose?.();
10636
+ } catch (error) {
10637
+ await retainPackageFaultBesideLivePlacement(request, {
10638
+ diagnostic: `required envelope shutdown failed beside host terminal: ${describeErrorIdentity(error)}`,
10639
+ error
10640
+ });
10641
+ if (outcome.code === 0 && !outcome.timedOut && outcome.signal === void 0 && outcome.knownFailure === void 0) {
10642
+ return { ...outcome, knownFailure: projectThrownFailureLeaf(error) };
10643
+ }
10644
+ }
10645
+ return outcome;
10646
+ }
10647
+ function createSerializedRoleTurnHost(execute) {
10648
+ let serial = Promise.resolve();
10649
+ return {
10650
+ executeTurn(request) {
10651
+ const execution = serial.then(() => execute(request));
10652
+ serial = execution.then(() => void 0, () => void 0);
10653
+ return execution;
10654
+ }
10655
+ };
10656
+ }
10657
+ var init_external_host_turn_loop = __esm({
10658
+ "src/external-host-turn-loop.ts"() {
10659
+ "use strict";
10660
+ init_activation_ledger_topology();
10661
+ init_settlement();
10662
+ init_run_lifecycle();
10663
+ init_receipt_delivery_policy();
10664
+ init_role_run_placement();
10665
+ init_role_run_relocation();
10666
+ init_sitian_facade();
10667
+ init_submission_errors();
10668
+ }
10669
+ });
10670
+
10448
10671
  // src/session-identity.ts
10449
10672
  import { dirname as dirname12, join as join15 } from "node:path";
10450
10673
  function createSessionIdentityAuthority(authority, hostName) {
@@ -10524,6 +10747,7 @@ __export(role_turn_host_exports, {
10524
10747
  });
10525
10748
  import { execFile as execFile2, spawn as spawn2 } from "node:child_process";
10526
10749
  import { constants } from "node:fs";
10750
+ import { existsSync as existsSync7 } from "node:fs";
10527
10751
  import { access as access2, appendFile, realpath as realpath4 } from "node:fs/promises";
10528
10752
  import { delimiter, dirname as dirname13, isAbsolute as isAbsolute6, join as join16, resolve as resolve12 } from "node:path";
10529
10753
  import { platform } from "node:process";
@@ -10709,7 +10933,32 @@ function createDefaultPiSpawnRunner(options) {
10709
10933
  if (stdinDeliveryError !== void 0) packageErrors.push(stdinDeliveryError);
10710
10934
  for (const error of packageErrors) {
10711
10935
  const diagnostic = `Pi transport handling failed beside host terminal: ${describeErrorIdentity(error)}`;
10712
- const runDirectory = spawnOptions.env.AK_ROLE_RUN_DIR;
10936
+ const spawnDir = spawnOptions.env.AK_ROLE_RUN_DIR;
10937
+ let runDirectory;
10938
+ if (typeof spawnDir === "string" && spawnDir.trim() !== "") {
10939
+ try {
10940
+ runDirectory = await resolveLiveRunDirectoryPath(
10941
+ spawnDir,
10942
+ homeFromRunDirectory(spawnDir)
10943
+ );
10944
+ } catch (resolveError) {
10945
+ runDirectory = existsSync7(spawnDir) ? spawnDir : void 0;
10946
+ const resolveDiagnostic = `live run path resolve failed beside Pi transport fault: ${describeErrorIdentity(resolveError)}`;
10947
+ if (runDirectory !== void 0) {
10948
+ await retainPackageFault({
10949
+ runDirectory,
10950
+ diagnostic: resolveDiagnostic,
10951
+ error: resolveError
10952
+ });
10953
+ } else {
10954
+ try {
10955
+ process.stderr.write(`${resolveDiagnostic}
10956
+ `);
10957
+ } catch {
10958
+ }
10959
+ }
10960
+ }
10961
+ }
10713
10962
  if (runDirectory !== void 0) {
10714
10963
  await retainPackageFault({ runDirectory, diagnostic, error });
10715
10964
  } else {
@@ -10791,6 +11040,7 @@ function createPiRoleTurnHost(config) {
10791
11040
  ...request.signal === void 0 ? {} : { signal: request.signal }
10792
11041
  });
10793
11042
  try {
11043
+ await syncTurnRequestLivePlacement(request);
10794
11044
  const { sessionFile, sessionDirectory } = config.principalAuthority.decode(request.principal);
10795
11045
  const sessionId = await readPiSessionHeaderId(sessionFile);
10796
11046
  if (sessionId !== void 0) {
@@ -10808,8 +11058,7 @@ function createPiRoleTurnHost(config) {
10808
11058
  });
10809
11059
  }
10810
11060
  } catch (error) {
10811
- await retainPackageFault({
10812
- runDirectory: request.runDirectory,
11061
+ await retainPackageFaultBesideLivePlacement(request, {
10813
11062
  diagnostic: `pi host dossier record failed beside host terminal: ${describeErrorIdentity(error)}`,
10814
11063
  error
10815
11064
  });
@@ -10878,6 +11127,8 @@ var init_role_turn_host = __esm({
10878
11127
  init_user_dialogue_stdin();
10879
11128
  init_ledger_session_read();
10880
11129
  init_host_session_record();
11130
+ init_external_host_turn_loop();
11131
+ init_activation_ledger_topology();
10881
11132
  init_settlement();
10882
11133
  init_run_lifecycle();
10883
11134
  init_receipt_delivery_policy();
@@ -11056,7 +11307,7 @@ var init_host_providers = __esm({
11056
11307
  });
11057
11308
 
11058
11309
  // src/public-cli/load-production-acp-host.ts
11059
- import { existsSync as existsSync6 } from "node:fs";
11310
+ import { existsSync as existsSync8 } from "node:fs";
11060
11311
  import { join as join18 } from "node:path";
11061
11312
  import { pathToFileURL } from "node:url";
11062
11313
  async function loadProductionAcpHostFactory(packageRoot, host) {
@@ -11066,7 +11317,7 @@ async function loadProductionAcpHostFactory(packageRoot, host) {
11066
11317
  }
11067
11318
  const built = join18(packageRoot, "dist/acp-host/production-host.js");
11068
11319
  const source = join18(packageRoot, "src/acp-host/production-host.ts");
11069
- const target = existsSync6(built) ? built : source;
11320
+ const target = existsSync8(built) ? built : source;
11070
11321
  const href = pathToFileURL(target).href;
11071
11322
  const mod = await import(href);
11072
11323
  const create = mod.createProductionAcpRoleTurnHost;
@@ -11080,7 +11331,7 @@ var init_load_production_acp_host = __esm({
11080
11331
  });
11081
11332
 
11082
11333
  // src/public-cli/load-production-headless-host.ts
11083
- import { existsSync as existsSync7 } from "node:fs";
11334
+ import { existsSync as existsSync9 } from "node:fs";
11084
11335
  import { join as join19 } from "node:path";
11085
11336
  import { pathToFileURL as pathToFileURL2 } from "node:url";
11086
11337
  async function loadProductionHeadlessHostFactory(packageRoot, host) {
@@ -11090,7 +11341,7 @@ async function loadProductionHeadlessHostFactory(packageRoot, host) {
11090
11341
  }
11091
11342
  const built = join19(packageRoot, "dist/headless-host/production-host.js");
11092
11343
  const source = join19(packageRoot, "src/headless-host/production-host.ts");
11093
- const target = existsSync7(built) ? built : source;
11344
+ const target = existsSync9(built) ? built : source;
11094
11345
  const href = pathToFileURL2(target).href;
11095
11346
  const mod = await import(href);
11096
11347
  const create = mod.createProductionHeadlessRoleTurnHost;
@@ -11256,8 +11507,179 @@ var init_role_seat_runtime = __esm({
11256
11507
  }
11257
11508
  });
11258
11509
 
11510
+ // src/report-ticket-tool.ts
11511
+ import { Type as Type16 } from "typebox";
11512
+ import { existsSync as existsSync10 } from "node:fs";
11513
+ function pageString(page, key) {
11514
+ const value = page?.[key];
11515
+ return typeof value === "string" && value.trim() !== "" ? value : void 0;
11516
+ }
11517
+ function admittedForLiveTicketReport(runDirectory, authority) {
11518
+ const admittedPage = readPageSync(runDirectory, "admitted") ?? {};
11519
+ const invocationPage = readPageSync(runDirectory, "invocation") ?? {};
11520
+ const role = pageString(admittedPage, "role") ?? pageString(invocationPage, "role");
11521
+ const runId = pageString(admittedPage, "runId") ?? pageString(invocationPage, "runId");
11522
+ const bookKey = pageString(admittedPage, "bookKey") ?? pageString(invocationPage, "bookKey");
11523
+ const projectRoot = pageString(admittedPage, "projectRoot") ?? pageString(invocationPage, "projectRoot");
11524
+ if (role === void 0 || runId === void 0 || bookKey === void 0 || projectRoot === void 0) {
11525
+ throw new Error("ak_report_ticket requires durable role/runId/bookKey/projectRoot on the run");
11526
+ }
11527
+ const attachments = Array.isArray(admittedPage.attachments) ? admittedPage.attachments : [];
11528
+ const sessionDirectory = sessionDirectoryOf(runDirectory);
11529
+ const sessionFile = sessionFileOf(runDirectory);
11530
+ const principal = authority.seal({ sessionDirectory, sessionFile });
11531
+ const ticketNumber = readDeclaredTicketNumber(admittedPage.ticketNumber) ?? readDeclaredTicketNumber(invocationPage.ticketNumber);
11532
+ return {
11533
+ role,
11534
+ runId,
11535
+ bookKey,
11536
+ projectRoot,
11537
+ instruction: typeof admittedPage.instruction === "string" ? admittedPage.instruction : "",
11538
+ instructionEmpty: admittedPage.instructionEmpty === true || typeof admittedPage.instruction === "string" && admittedPage.instruction.trim() === "",
11539
+ attachments,
11540
+ runDirectory,
11541
+ principal,
11542
+ ...ticketNumber === void 0 ? {} : { ticketNumber }
11543
+ };
11544
+ }
11545
+ async function reportTicketFromHostContext(context, rawTicketNumber, authority = piDurablePrincipalAuthority) {
11546
+ const ticketNumber = readDeclaredTicketNumber(rawTicketNumber);
11547
+ if (ticketNumber === void 0) {
11548
+ throw new Error("ak_report_ticket requires an identifiable ticketNumber");
11549
+ }
11550
+ const runDirectory = runDirectoryFromHostContext(context);
11551
+ if (runDirectory === void 0) {
11552
+ throw new Error("ak_report_ticket requires a per-turn run directory");
11553
+ }
11554
+ if (!existsSync10(runDirectory)) {
11555
+ throw new Error(`ak_report_ticket run directory missing: ${runDirectory}`);
11556
+ }
11557
+ const admitted = admittedForLiveTicketReport(runDirectory, authority);
11558
+ const alreadyPlaced = !isUnboundRunDirectory(runDirectory);
11559
+ if (!alreadyPlaced) {
11560
+ await bindAdmittedTicketNumber(admitted, ticketNumber);
11561
+ }
11562
+ const applyLiveHandles = (nextDirectory2) => {
11563
+ context.runDirectory = nextDirectory2;
11564
+ if (process.env.AK_ROLE_RUN_DIR === runDirectory) {
11565
+ process.env.AK_ROLE_RUN_DIR = nextDirectory2;
11566
+ }
11567
+ context.sessionManager.setSessionFile?.(sessionFileOf(nextDirectory2));
11568
+ };
11569
+ const relocation = alreadyPlaced ? void 0 : await relocateAdmittedRunToTicket(admitted, authority, { relocate: applyLiveHandles });
11570
+ const nextDirectory = relocation?.newRunDirectory ?? admitted.runDirectory;
11571
+ if (relocation === void 0) applyLiveHandles(nextDirectory);
11572
+ return {
11573
+ ticketNumber: alreadyPlaced ? admitted.ticketNumber ?? ticketNumber : ticketNumber,
11574
+ relocated: relocation !== void 0
11575
+ };
11576
+ }
11577
+ function registerReportTicketTool(roleHost) {
11578
+ if (roleHost.getAllTools().some((tool) => tool.name === REPORT_TICKET_TOOL_NAME)) return;
11579
+ roleHost.registerTool({
11580
+ name: REPORT_TICKET_TOOL_NAME,
11581
+ label: "\u62A5\u7968\u53F7",
11582
+ description: REPORT_TICKET_TOOL_DESCRIPTION,
11583
+ promptSnippet: "\u5DF2\u77E5\u7968\u53F7\u65F6\u7ACB\u5373\u7533\u62A5\uFF0C\u5305\u5F53\u573A\u5F52\u4F4D",
11584
+ parameters: reportTicketArgsSchema,
11585
+ async execute(_toolCallId, parameters, _signal, _onUpdate, ctx) {
11586
+ const raw = isRecord(parameters) ? parameters.ticketNumber : void 0;
11587
+ const details = await reportTicketFromHostContext(ctx, raw);
11588
+ return {
11589
+ content: [],
11590
+ details
11591
+ };
11592
+ }
11593
+ });
11594
+ }
11595
+ var REPORT_TICKET_TOOL_NAME, reportTicketArgsSchema, REPORT_TICKET_TOOL_DESCRIPTION, MISSING_TICKET_REASK_MATERIAL;
11596
+ var init_report_ticket_tool = __esm({
11597
+ "src/report-ticket-tool.ts"() {
11598
+ "use strict";
11599
+ init_host_contracts();
11600
+ init_durable_principal();
11601
+ init_invocation();
11602
+ init_role_run_placement();
11603
+ init_run_dossier();
11604
+ init_run_ticket_number();
11605
+ init_unknown_value();
11606
+ REPORT_TICKET_TOOL_NAME = "ak_report_ticket";
11607
+ reportTicketArgsSchema = Type16.Object(
11608
+ {
11609
+ ticketNumber: Type16.Unknown({
11610
+ description: "\u672C\u7968\u53F7\uFF08\u6B63\u6574\u6570\u3001\u6570\u5B57\u4E32\u6216\u524D\u5BFC #N\uFF09\u3002\u5DF2\u77E5\u7968\u53F7\u65F6\u5F00\u5DE5\u5373\u62A5\uFF1B\u5C1A\u65E0\u7968\u53F7\u65F6\u4E0D\u8981\u8C03\u7528\u3002"
11611
+ })
11612
+ },
11613
+ { additionalProperties: true }
11614
+ );
11615
+ REPORT_TICKET_TOOL_DESCRIPTION = "\u5411\u5305\u7533\u62A5\u672C\u7968\u53F7\u3002\u5DF2\u77E5\u7968\u53F7\u65F6\u5F00\u5DE5\u7B2C\u4E00\u4EF6\u4E8B\u8C03\u7528\uFF1B\u5305\u5F53\u573A\u628A\u672C\u817F\u5F52\u5230\u7968\u53F7\u76EE\u5F55\u3002\u5C1A\u65E0\u7968\u53F7\uFF08\u4F8B\u5982\u4E2D\u4E66\u7701\u5EFA\u7968\u524D\uFF09\u4E0D\u8981\u8C03\u7528\uFF0C\u53D6\u5F97\u540E\u518D\u62A5\u3002\u4EA4\u5377\u65F6\u82E5\u4ECD\u672A\u62A5\u8FC7\u4E14\u4EA4\u5377\u4EA6\u672A\u5E26\u7968\u53F7\uFF0C\u5305\u4F1A\u7ECF\u65E2\u6709\u91CD\u4EA4\u901A\u9053\u518D\u95EE\u4E00\u6B21\u3002";
11616
+ MISSING_TICKET_REASK_MATERIAL = "resources/missing-ticket-reask.md";
11617
+ }
11618
+ });
11619
+
11620
+ // src/session-opening-materials.ts
11621
+ import { existsSync as existsSync11 } from "node:fs";
11622
+ import { readFile as readFile10 } from "node:fs/promises";
11623
+ import { dirname as dirname14, join as join20 } from "node:path";
11624
+ import { fileURLToPath, pathToFileURL as pathToFileURL3 } from "node:url";
11625
+ function resolvePackageRootDir(moduleUrl = import.meta.url) {
11626
+ let dir = dirname14(fileURLToPath(moduleUrl));
11627
+ for (let i = 0; i < 8; i += 1) {
11628
+ if (existsSync11(join20(dir, "package.json")) && existsSync11(join20(dir, "souls"))) {
11629
+ return dir;
11630
+ }
11631
+ const parent = dirname14(dir);
11632
+ if (parent === dir) break;
11633
+ dir = parent;
11634
+ }
11635
+ return fileURLToPath(new URL("..", moduleUrl));
11636
+ }
11637
+ async function readPackageMaterial(relativePath) {
11638
+ return readFile10(fileURLToPath(new URL(relativePath, packageRootUrl)), "utf8");
11639
+ }
11640
+ async function joinPackageMaterials(relativePaths) {
11641
+ const chunks = [];
11642
+ for (const relativePath of relativePaths) chunks.push(await readPackageMaterial(relativePath));
11643
+ return chunks.join("\n\n");
11644
+ }
11645
+ function roleSoulPath(role, materials) {
11646
+ const suffix = `/souls/${role}.md`;
11647
+ const path = materials.find((candidate) => `/${candidate}`.endsWith(suffix));
11648
+ if (path === void 0) throw new Error(`session materials omit the ${role} Soul`);
11649
+ return path;
11650
+ }
11651
+ async function loadSeparatedSessionPart(role, materials, part) {
11652
+ const soul = roleSoulPath(role, materials);
11653
+ return part === "soul" ? readPackageMaterial(soul) : joinPackageMaterials(materials.filter((path) => path !== soul));
11654
+ }
11655
+ function loadMainRoleSessionMaterials(role) {
11656
+ return loadSeparatedSessionPart(role, MAIN_ROLE_SESSION_MATERIALS[role], "soul");
11657
+ }
11658
+ function loadMainRoleReferenceMaterials(role) {
11659
+ return loadSeparatedSessionPart(role, MAIN_ROLE_SESSION_MATERIALS[role], "references");
11660
+ }
11661
+ var packageRootUrl, MAIN_ROLE_SESSION_MATERIALS, GATEKEEPER_SESSION_MATERIALS;
11662
+ var init_session_opening_materials = __esm({
11663
+ "src/session-opening-materials.ts"() {
11664
+ "use strict";
11665
+ init_packaged_role_registry();
11666
+ packageRootUrl = pathToFileURL3(resolvePackageRootDir() + "/").href;
11667
+ MAIN_ROLE_SESSION_MATERIALS = {
11668
+ ...Object.fromEntries(
11669
+ PUBLIC_ROLE_RECORDS.map((record) => [record.role, record.sessionMaterials])
11670
+ )
11671
+ };
11672
+ GATEKEEPER_SESSION_MATERIALS = {
11673
+ // #639: single authority — the public gatekeeper record owns the province list.
11674
+ gatekeeper: packagedRoleSessionMaterials("gatekeeper"),
11675
+ inspector: INSPECTOR_SESSION_MATERIALS,
11676
+ notary: NOTARY_SESSION_MATERIALS
11677
+ };
11678
+ }
11679
+ });
11680
+
11259
11681
  // src/archivist-record-pointer.ts
11260
- import { basename as basename9, join as join20 } from "node:path";
11682
+ import { basename as basename10, join as join21 } from "node:path";
11261
11683
  function bookDirectOfficerRunPointer(options) {
11262
11684
  const submissionToolCallId = options.submissionToolCallId?.trim() ?? "";
11263
11685
  const pointer = {
@@ -11283,7 +11705,7 @@ async function resolveOfficerPointer(raw, parentRunDirectory) {
11283
11705
  let runDirectory = typeof raw.runDirectory === "string" && raw.runDirectory.trim() !== "" ? raw.runDirectory : void 0;
11284
11706
  let sessionFile = raw.sessionFile;
11285
11707
  const recordedRunDirectory = runDirectory ?? runDirectoryOfSessionFile(sessionFile);
11286
- const leaf = parseRunLeaf(basename9(recordedRunDirectory));
11708
+ const leaf = parseRunLeaf(basename10(recordedRunDirectory));
11287
11709
  const parentIdentity = await readRoleRunIdentity(parentRunDirectory);
11288
11710
  if (leaf !== void 0 && parentIdentity !== void 0) {
11289
11711
  const currentRunDirectory = await findRunDirectoryById(
@@ -11306,7 +11728,7 @@ async function resolveOfficerPointer(raw, parentRunDirectory) {
11306
11728
  };
11307
11729
  }
11308
11730
  async function readBookedOfficerPointers(parentRunDirectory) {
11309
- const { records, diagnostics } = await readSitianRecords(join20(parentRunDirectory, RUN_HISTORY_FILE));
11731
+ const { records, diagnostics } = await readSitianRecords(join21(parentRunDirectory, RUN_HISTORY_FILE));
11310
11732
  if (diagnostics.length > 0) {
11311
11733
  throw new Error(
11312
11734
  `${RUN_HISTORY_FILE} has ${diagnostics.length} malformed row(s); officer pointers unreadable: ${parentRunDirectory}`
@@ -11642,67 +12064,6 @@ var init_submission_gate = __esm({
11642
12064
  }
11643
12065
  });
11644
12066
 
11645
- // src/session-opening-materials.ts
11646
- import { existsSync as existsSync8 } from "node:fs";
11647
- import { readFile as readFile10 } from "node:fs/promises";
11648
- import { dirname as dirname14, join as join21 } from "node:path";
11649
- import { fileURLToPath, pathToFileURL as pathToFileURL3 } from "node:url";
11650
- function resolvePackageRootDir(moduleUrl = import.meta.url) {
11651
- let dir = dirname14(fileURLToPath(moduleUrl));
11652
- for (let i = 0; i < 8; i += 1) {
11653
- if (existsSync8(join21(dir, "package.json")) && existsSync8(join21(dir, "souls"))) {
11654
- return dir;
11655
- }
11656
- const parent = dirname14(dir);
11657
- if (parent === dir) break;
11658
- dir = parent;
11659
- }
11660
- return fileURLToPath(new URL("..", moduleUrl));
11661
- }
11662
- async function readPackageMaterial(relativePath) {
11663
- return readFile10(fileURLToPath(new URL(relativePath, packageRootUrl)), "utf8");
11664
- }
11665
- async function joinPackageMaterials(relativePaths) {
11666
- const chunks = [];
11667
- for (const relativePath of relativePaths) chunks.push(await readPackageMaterial(relativePath));
11668
- return chunks.join("\n\n");
11669
- }
11670
- function roleSoulPath(role, materials) {
11671
- const suffix = `/souls/${role}.md`;
11672
- const path = materials.find((candidate) => `/${candidate}`.endsWith(suffix));
11673
- if (path === void 0) throw new Error(`session materials omit the ${role} Soul`);
11674
- return path;
11675
- }
11676
- async function loadSeparatedSessionPart(role, materials, part) {
11677
- const soul = roleSoulPath(role, materials);
11678
- return part === "soul" ? readPackageMaterial(soul) : joinPackageMaterials(materials.filter((path) => path !== soul));
11679
- }
11680
- function loadMainRoleSessionMaterials(role) {
11681
- return loadSeparatedSessionPart(role, MAIN_ROLE_SESSION_MATERIALS[role], "soul");
11682
- }
11683
- function loadMainRoleReferenceMaterials(role) {
11684
- return loadSeparatedSessionPart(role, MAIN_ROLE_SESSION_MATERIALS[role], "references");
11685
- }
11686
- var packageRootUrl, MAIN_ROLE_SESSION_MATERIALS, GATEKEEPER_SESSION_MATERIALS;
11687
- var init_session_opening_materials = __esm({
11688
- "src/session-opening-materials.ts"() {
11689
- "use strict";
11690
- init_packaged_role_registry();
11691
- packageRootUrl = pathToFileURL3(resolvePackageRootDir() + "/").href;
11692
- MAIN_ROLE_SESSION_MATERIALS = {
11693
- ...Object.fromEntries(
11694
- PUBLIC_ROLE_RECORDS.map((record) => [record.role, record.sessionMaterials])
11695
- )
11696
- };
11697
- GATEKEEPER_SESSION_MATERIALS = {
11698
- // #639: single authority — the public gatekeeper record owns the province list.
11699
- gatekeeper: packagedRoleSessionMaterials("gatekeeper"),
11700
- inspector: INSPECTOR_SESSION_MATERIALS,
11701
- notary: NOTARY_SESSION_MATERIALS
11702
- };
11703
- }
11704
- });
11705
-
11706
12067
  // src/auditor-soul.ts
11707
12068
  var auditor_soul_exports = {};
11708
12069
  __export(auditor_soul_exports, {
@@ -11718,7 +12079,7 @@ __export(auditor_soul_exports, {
11718
12079
  readAuditorResumeBinding: () => readAuditorResumeBinding,
11719
12080
  resolveAuditorSubject: () => resolveAuditorSubject
11720
12081
  });
11721
- import { basename as basename10 } from "node:path";
12082
+ import { basename as basename11 } from "node:path";
11722
12083
  function auditorSoulRelativePath(role) {
11723
12084
  return `souls/${role}-auditor.md`;
11724
12085
  }
@@ -11754,7 +12115,7 @@ function loadAuditorReferenceMaterialsFromSubjectInput(raw) {
11754
12115
  return loadAuditorReferenceMaterials(resolveAuditorSubject(raw));
11755
12116
  }
11756
12117
  function subjectFromSourceDirectory(sourceRunDirectory) {
11757
- const role = parseRunLeaf(basename10(sourceRunDirectory))?.role;
12118
+ const role = parseRunLeaf(basename11(sourceRunDirectory))?.role;
11758
12119
  return isAuditorSoulRole(role) ? role : void 0;
11759
12120
  }
11760
12121
  async function readAuditorResumeBinding(runDirectory) {
@@ -12316,6 +12677,7 @@ var init_auto_resume = __esm({
12316
12677
 
12317
12678
  // src/public-cli/post-admission.ts
12318
12679
  import { randomUUID as randomUUID6 } from "node:crypto";
12680
+ import { existsSync as existsSync12 } from "node:fs";
12319
12681
  function describeCaughtError(error) {
12320
12682
  if (error instanceof Error) {
12321
12683
  const code = error.code;
@@ -12348,6 +12710,91 @@ function projectRelocatedTurnIdentity(request, result, admitted, relocation) {
12348
12710
  }
12349
12711
  }
12350
12712
  }
12713
+ async function refreshAdmittedPlacementAfterHostTurn(admitted, authority, heldLease) {
12714
+ const home = homeFromRunDirectory(admitted.runDirectory);
12715
+ const found = await findRunDirectoryById(home, admitted.runId, admitted.bookKey, admitted.role);
12716
+ if (found === void 0 && !existsSync12(admitted.runDirectory)) {
12717
+ throw new Error(
12718
+ `admitted run ${admitted.runId} missing after host turn; not found under ${home}`
12719
+ );
12720
+ }
12721
+ let relocation;
12722
+ if (found !== void 0 && found !== admitted.runDirectory) {
12723
+ const oldRunDirectory = admitted.runDirectory;
12724
+ const coords = { ...authority.decode(admitted.principal) };
12725
+ rewritePrincipalSessionPaths(
12726
+ coords,
12727
+ oldRunDirectory,
12728
+ found
12729
+ );
12730
+ const principal = authority.seal(coords);
12731
+ rewriteAdmittedRoleRunPage(
12732
+ admitted,
12733
+ [{ oldRunDirectory, newRunDirectory: found }]
12734
+ );
12735
+ admitted.principal = principal;
12736
+ heldLease?.relocate(found);
12737
+ relocation = { oldRunDirectory, newRunDirectory: found };
12738
+ }
12739
+ if (admitted.ticketNumber === void 0) {
12740
+ const boardTicket = await readBoardTicketNumber(found ?? admitted.runDirectory);
12741
+ if (boardTicket !== void 0) {
12742
+ admitted.ticketNumber = boardTicket;
12743
+ }
12744
+ }
12745
+ return relocation;
12746
+ }
12747
+ function applyRefreshedPlacementToTurn(request, turnRequest, admitted, refreshed) {
12748
+ projectRelocatedTurnIdentity(request, {}, admitted, refreshed);
12749
+ return {
12750
+ ...turnRequest,
12751
+ runDirectory: admitted.runDirectory,
12752
+ principal: admitted.principal
12753
+ };
12754
+ }
12755
+ async function settleHostThrowAfterLivePlacementRefresh(input) {
12756
+ let refreshError;
12757
+ let turnRequest = input.turnRequest;
12758
+ try {
12759
+ const refreshed = await refreshAdmittedPlacementAfterHostTurn(
12760
+ input.admitted,
12761
+ input.env.principalAuthority,
12762
+ input.lease
12763
+ );
12764
+ if (refreshed !== void 0) {
12765
+ turnRequest = applyRefreshedPlacementToTurn(
12766
+ input.request,
12767
+ turnRequest,
12768
+ input.admitted,
12769
+ refreshed
12770
+ );
12771
+ }
12772
+ } catch (err) {
12773
+ refreshError = err;
12774
+ }
12775
+ const processCancelName = processCancelSignalName(input.env.signal);
12776
+ const hostThrowSecondary = refreshError !== void 0 && input.hostTurnCompleted === false ? { knownDetails: { hostThrow: describeCaughtError(input.hostError) } } : {};
12777
+ const settled = await settleAfterTurnStarted(
12778
+ input.admitted,
12779
+ withEngineDetourInvocationScope({
12780
+ timedOut: false,
12781
+ code: null,
12782
+ stderr: "",
12783
+ // Prefer the refresh failure when the live path is gone; otherwise the
12784
+ // host throw remains the cause (失败诚实:不在旧 unbound 上结算写回).
12785
+ ...processCancelName === void 0 ? {} : { cancelName: processCancelName },
12786
+ thrown: refreshError ?? input.hostError,
12787
+ ...hostThrowSecondary
12788
+ }, input.request.invocationScopeId),
12789
+ input.adapters,
12790
+ input.env.principalAuthority,
12791
+ input.io,
12792
+ input.persistRunState,
12793
+ input.notePackageFault,
12794
+ input.courtAttemptId
12795
+ );
12796
+ return { settled, turnRequest };
12797
+ }
12351
12798
  function withProcessCancelSkipAutoResume(result, signal) {
12352
12799
  if (processCancelSignalName(signal) === void 0) {
12353
12800
  return result;
@@ -12734,6 +13181,12 @@ async function dispatchPostAdmissionTurn(input) {
12734
13181
  }
12735
13182
  if (pendingSettlement !== void 0 && pendingTerminal !== void 0 && result.terminal === pendingTerminal) {
12736
13183
  try {
13184
+ const softTicketReaskNoSeal = pendingSettlement !== "sealed" && env.softTicketReaskTurn === true;
13185
+ const noSealScope = softTicketReaskNoSeal ? {
13186
+ ...courtScope,
13187
+ previewOnly: true,
13188
+ recordAttemptHistory: true
13189
+ } : { ...courtScope, recordAttemptHistory: true };
12737
13190
  const terminal = pendingSettlement === "sealed" ? await adapters.trySettle(
12738
13191
  admitted,
12739
13192
  env.principalAuthority,
@@ -12743,13 +13196,16 @@ async function dispatchPostAdmissionTurn(input) {
12743
13196
  await settleHostEndedNoReceipt(
12744
13197
  admitted,
12745
13198
  env.principalAuthority,
12746
- { ...courtScope, recordAttemptHistory: true },
13199
+ noSealScope,
12747
13200
  receiptDelivery.issuedDeliveryRequests()
12748
13201
  ),
12749
- courtScope
13202
+ noSealScope
12750
13203
  );
12751
13204
  if (terminal === void 0) throw new Error("settled host attempt vanished before publication");
12752
13205
  result = { ...result, terminal, exitCode: exitCodeForTerminalOutcome(terminal.roleOutcome) };
13206
+ if (pendingSettlement === "sealed" && env.softTicketReaskTurn === true && env.softTicketReaskOwnership !== void 0) {
13207
+ env.softTicketReaskOwnership.sealedSubstitute = true;
13208
+ }
12753
13209
  if (pendingSettlement === "sealed" && terminal.roleOutcome.kind === "accepted" && request.courtAttemptId !== void 0 && request.courtAttemptId.length > 0) {
12754
13210
  try {
12755
13211
  await clearCurrentCourt(admitted.runDirectory, request.courtAttemptId);
@@ -12859,32 +13315,38 @@ async function dispatchPostAdmissionTurn(input) {
12859
13315
  env.engineModel
12860
13316
  );
12861
13317
  let result;
13318
+ let hostTurnCompleted = false;
12862
13319
  try {
12863
13320
  turnDispatched = true;
12864
13321
  result = await env.roleTurnHost.executeTurn(turnRequest);
13322
+ hostTurnCompleted = true;
13323
+ const refreshed = await refreshAdmittedPlacementAfterHostTurn(
13324
+ admitted,
13325
+ env.principalAuthority,
13326
+ lease
13327
+ );
13328
+ if (refreshed !== void 0) {
13329
+ turnRequest = applyRefreshedPlacementToTurn(request, turnRequest, admitted, refreshed);
13330
+ }
12865
13331
  } catch (error) {
12866
- const processCancelName = processCancelSignalName(env.signal);
12867
- const settled = await settleAfterTurnStarted(
13332
+ const thrown = await settleHostThrowAfterLivePlacementRefresh({
12868
13333
  admitted,
12869
- withEngineDetourInvocationScope({
12870
- timedOut: false,
12871
- code: null,
12872
- stderr: "",
12873
- // The thrown value is the host's report. A cancel received on this
12874
- // call is a second fact; it must not become a new Error in its place.
12875
- ...processCancelName === void 0 ? {} : { cancelName: processCancelName },
12876
- thrown: error
12877
- }, request.invocationScopeId),
13334
+ hostError: error,
13335
+ hostTurnCompleted,
13336
+ request,
13337
+ turnRequest,
13338
+ lease,
12878
13339
  adapters,
12879
- env.principalAuthority,
13340
+ env,
12880
13341
  io,
12881
13342
  persistRunState,
12882
- courtScope.notePackageFault,
12883
- courtScope.courtAttemptId
12884
- );
13343
+ notePackageFault: courtScope.notePackageFault,
13344
+ ...courtScope.courtAttemptId === void 0 ? {} : { courtAttemptId: courtScope.courtAttemptId }
13345
+ });
13346
+ turnRequest = thrown.turnRequest;
12885
13347
  return await finishAfterTurn(
12886
13348
  withProcessCancelSkipAutoResume(
12887
- { ...settled, turnDispatched: true, ...deferredPersist },
13349
+ { ...thrown.settled, turnDispatched: true, ...deferredPersist },
12888
13350
  env.signal
12889
13351
  )
12890
13352
  );
@@ -12910,6 +13372,7 @@ async function dispatchPostAdmissionTurn(input) {
12910
13372
  while (akSeamDeliversReceipt && receiptDelivery.nextAction() === "request-delivery") {
12911
13373
  let deliveryResult;
12912
13374
  let deliveryTurnRequest;
13375
+ let deliveryHostTurnCompleted = false;
12913
13376
  try {
12914
13377
  const deliveryRequest = buildReceiptDeliveryRequest({
12915
13378
  request: turnRequest,
@@ -12923,24 +13386,40 @@ async function dispatchPostAdmissionTurn(input) {
12923
13386
  };
12924
13387
  receiptDelivery.recordDeliveryRequest();
12925
13388
  deliveryResult = await env.roleTurnHost.executeTurn(deliveryTurnRequest);
13389
+ deliveryHostTurnCompleted = true;
13390
+ const refreshed = await refreshAdmittedPlacementAfterHostTurn(
13391
+ admitted,
13392
+ env.principalAuthority,
13393
+ lease
13394
+ );
13395
+ if (refreshed !== void 0) {
13396
+ turnRequest = applyRefreshedPlacementToTurn(request, turnRequest, admitted, refreshed);
13397
+ deliveryTurnRequest = {
13398
+ ...deliveryTurnRequest,
13399
+ runDirectory: admitted.runDirectory,
13400
+ principal: admitted.principal
13401
+ };
13402
+ }
12926
13403
  } catch (error) {
12927
- const settled = await settleAfterTurnStarted(
13404
+ const thrown = await settleHostThrowAfterLivePlacementRefresh({
12928
13405
  admitted,
12929
- withEngineDetourInvocationScope(
12930
- { timedOut: false, code: null, stderr: "", thrown: error },
12931
- request.invocationScopeId
12932
- ),
13406
+ hostError: error,
13407
+ hostTurnCompleted: deliveryHostTurnCompleted,
13408
+ request,
13409
+ turnRequest,
13410
+ lease,
12933
13411
  adapters,
12934
- env.principalAuthority,
13412
+ env,
12935
13413
  io,
12936
13414
  persistRunState,
12937
- courtScope.notePackageFault,
12938
- courtScope.courtAttemptId
12939
- );
13415
+ notePackageFault: courtScope.notePackageFault,
13416
+ ...courtScope.courtAttemptId === void 0 ? {} : { courtAttemptId: courtScope.courtAttemptId }
13417
+ });
13418
+ turnRequest = thrown.turnRequest;
12940
13419
  return await finishAfterTurn(
12941
13420
  withProcessCancelSkipAutoResume(
12942
13421
  {
12943
- ...settled,
13422
+ ...thrown.settled,
12944
13423
  turnDispatched: true,
12945
13424
  ...deferredPersist
12946
13425
  },
@@ -13456,6 +13935,7 @@ var init_post_admission = __esm({
13456
13935
  init_invocation();
13457
13936
  init_submission_ledger();
13458
13937
  init_run_ticket_number();
13938
+ init_activation_ledger_topology();
13459
13939
  init_session_identity();
13460
13940
  init_sitian_facade();
13461
13941
  init_receipt_delivery_policy();
@@ -13604,10 +14084,14 @@ function unreadablePostSubmissionStatus(admitted, terminal) {
13604
14084
  const status = receivedDiscriminator(payload, "status");
13605
14085
  return typeof status === "string" && route.statuses.has(status) ? void 0 : route.reask ?? officerConclusionReask(status);
13606
14086
  }
14087
+ function withoutSoftTicketReaskTurn(env) {
14088
+ const { softTicketReaskTurn: _softTicketReaskTurn, ...rest } = env;
14089
+ return rest;
14090
+ }
13607
14091
  function withUnreadableReask(env) {
13608
14092
  const spent = env.unreadableReasksSpent ?? 0;
13609
14093
  if (spent >= deliveryLimitFromConfig(env.autoResumeLimit)) return void 0;
13610
- return { ...env, unreadableReasksSpent: spent + 1 };
14094
+ return { ...withoutSoftTicketReaskTurn(env), unreadableReasksSpent: spent + 1 };
13611
14095
  }
13612
14096
  function isUnreadableReaskExhausted(value) {
13613
14097
  return value === UNREADABLE_REASK_EXHAUSTED;
@@ -13666,6 +14150,110 @@ async function reaskUnreadablePostSubmissionStatus(admitted, terminal, env, io,
13666
14150
  io
13667
14151
  );
13668
14152
  }
14153
+ async function reaskMissingTicketOnce(admitted, terminal, env, io) {
14154
+ if ((env.ticketReasksSpent ?? 0) >= 1) return { kind: "none" };
14155
+ if (admitted.ticketNumber !== void 0) return { kind: "none" };
14156
+ if (!isUnboundRunDirectory(admitted.runDirectory)) return { kind: "none" };
14157
+ if (terminal?.roleOutcome.kind !== "accepted" && terminal?.roleOutcome.kind !== "audit_escalation") {
14158
+ return { kind: "none" };
14159
+ }
14160
+ const payloads = terminal.roleOutcome.payloads ?? [];
14161
+ if (payloads.length === 0) return { kind: "none" };
14162
+ const instruction = (await readPackageMaterial(MISSING_TICKET_REASK_MATERIAL)).trim();
14163
+ const softTicketReaskOwnership = { sealedSubstitute: false };
14164
+ const softReaskEnv = {
14165
+ ...env,
14166
+ ticketReasksSpent: 1,
14167
+ softTicketReaskTurn: true,
14168
+ softTicketReaskOwnership
14169
+ };
14170
+ const result = await runPublicInstructionSeatResume(
14171
+ { runId: admitted.runId, summons: { instruction } },
14172
+ softReaskEnv,
14173
+ io
14174
+ );
14175
+ if (softTicketReaskOwnership.sealedSubstitute || terminalCarriesSealedSubmission(result.terminal)) {
14176
+ return { kind: "nested_owns", result };
14177
+ }
14178
+ return { kind: "no_substitute", result };
14179
+ }
14180
+ function envForCourtContinue(env) {
14181
+ return { ...withoutSoftTicketReaskTurn(env), unreadableReasksSpent: 0 };
14182
+ }
14183
+ function terminalCarriesSealedSubmission(terminal) {
14184
+ const kind = terminal?.roleOutcome.kind;
14185
+ if (kind !== "accepted" && kind !== "audit_escalation") return false;
14186
+ return (terminal?.roleOutcome.payloads ?? []).length > 0;
14187
+ }
14188
+ function projectKeptOriginalArtifactsOntoLiveAdmitted(original, kept) {
14189
+ const oldRunDirectory = original.admitted?.runDirectory;
14190
+ const newRunDirectory = kept.admitted?.runDirectory;
14191
+ if (oldRunDirectory === void 0 || newRunDirectory === void 0 || oldRunDirectory === newRunDirectory || kept.terminal === void 0) {
14192
+ return;
14193
+ }
14194
+ for (const artifact of kept.terminal.artifacts) {
14195
+ artifact.path = rewriteRunDirectoryPathValue(
14196
+ artifact.path,
14197
+ oldRunDirectory,
14198
+ newRunDirectory
14199
+ );
14200
+ }
14201
+ }
14202
+ function mergeMissingTicketReaskKeepOriginal(original, ticketReask) {
14203
+ if (ticketReask.exitCode !== 0) return ticketReask;
14204
+ const admitted = ticketReask.admitted ?? original.admitted;
14205
+ if (admitted === void 0) return { ...original };
14206
+ const kept = { ...original, admitted };
14207
+ projectKeptOriginalArtifactsOntoLiveAdmitted(original, kept);
14208
+ return kept;
14209
+ }
14210
+ async function continueAfterPostSubmissionGuards(result, admittedRole, env, io, held) {
14211
+ const live = result.admitted;
14212
+ if (live === void 0) {
14213
+ await presentOriginalVolume(held, result.terminal, io);
14214
+ return result;
14215
+ }
14216
+ const unreadableReask = await reaskUnreadablePostSubmissionStatus(
14217
+ live,
14218
+ result.terminal,
14219
+ env,
14220
+ io
14221
+ );
14222
+ let afterStatus = result;
14223
+ if (isUnreadableReaskExhausted(unreadableReask)) {
14224
+ const terminal = result.terminal === void 0 ? void 0 : withUnsettledDirection(result.terminal);
14225
+ afterStatus = terminal === void 0 ? { ...result, admitted: live } : { ...result, admitted: live, terminal };
14226
+ } else if (unreadableReask !== void 0) {
14227
+ return unreadableReask;
14228
+ }
14229
+ const forTicket = afterStatus.admitted ?? live;
14230
+ const softReask = await reaskMissingTicketOnce(
14231
+ forTicket,
14232
+ afterStatus.terminal ?? result.terminal,
14233
+ env,
14234
+ io
14235
+ );
14236
+ if (softReask.kind === "nested_owns") {
14237
+ return softReask.result;
14238
+ }
14239
+ const continued = softReask.kind === "none" ? afterStatus : mergeMissingTicketReaskKeepOriginal(afterStatus, softReask.result);
14240
+ const continuedAdmitted = continued.admitted ?? live;
14241
+ const continuedEnv = softReask.kind !== "none" ? { ...env, ticketReasksSpent: 1 } : env;
14242
+ if (AUDITED_ROLES.has(admittedRole) && continued.terminal?.roleOutcome.kind === "accepted") {
14243
+ return auditSubmittedRole(
14244
+ { ...continued, admitted: continuedAdmitted },
14245
+ continuedEnv,
14246
+ io
14247
+ );
14248
+ }
14249
+ await presentOriginalVolume(
14250
+ held,
14251
+ continued.terminal,
14252
+ io,
14253
+ continuedAdmitted.runDirectory
14254
+ );
14255
+ return { ...continued, admitted: continuedAdmitted };
14256
+ }
13669
14257
  function roleRecord(role) {
13670
14258
  const record = packagedRoleMetadata(role);
13671
14259
  if (record === void 0) {
@@ -13840,23 +14428,14 @@ async function dispatchAdmitted(admitted, env, io) {
13840
14428
  });
13841
14429
  };
13842
14430
  const result = await execute(env);
13843
- const unreadableReask = await reaskUnreadablePostSubmissionStatus(
13844
- admitted,
13845
- result.terminal,
14431
+ const live = result.admitted ?? admitted;
14432
+ return continueAfterPostSubmissionGuards(
14433
+ { ...result, admitted: live },
14434
+ admitted.role,
13846
14435
  env,
13847
- io
14436
+ io,
14437
+ held
13848
14438
  );
13849
- if (isUnreadableReaskExhausted(unreadableReask)) {
13850
- const terminal = result.terminal === void 0 ? void 0 : withUnsettledDirection(result.terminal);
13851
- await presentOriginalVolume(held, terminal, io, admitted.runDirectory);
13852
- return terminal === void 0 ? result : { ...result, terminal };
13853
- }
13854
- if (unreadableReask !== void 0) return unreadableReask;
13855
- if (AUDITED_ROLES.has(admitted.role) && result.terminal?.roleOutcome.kind === "accepted") {
13856
- return auditSubmittedRole(result, env, io);
13857
- }
13858
- await presentOriginalVolume(held, result.terminal, io, admitted.runDirectory);
13859
- return result;
13860
14439
  }
13861
14440
  async function runOmittedLensBatch(argv, parsed, env, io) {
13862
14441
  const { summonParallelReviewerLenses: summonParallelReviewerLenses2 } = await Promise.resolve().then(() => (init_public_role_summons(), public_role_summons_exports));
@@ -14042,9 +14621,7 @@ async function runPublicInstructionSeat(argv, env, io, role, parseArgv2) {
14042
14621
  stdout: (value) => held.push(value),
14043
14622
  stderr: io.stderr
14044
14623
  });
14045
- if (result.terminal?.roleOutcome.kind === "accepted") return auditSubmittedRole(result, env, io);
14046
- await presentOriginalVolume(held, result.terminal, io, result.admitted?.runDirectory);
14047
- return result;
14624
+ return continueAfterPostSubmissionGuards(result, "countersign", env, io, held);
14048
14625
  }
14049
14626
  if ("parallelLenses" in record && record.parallelLenses === true) {
14050
14627
  if (parsed.baseRevision === void 0) {
@@ -14318,23 +14895,17 @@ async function runPublicInstructionSeatResume(request, env, io) {
14318
14895
  },
14319
14896
  ...env.engine === void 0 ? {} : { effectiveEngine: env.engine }
14320
14897
  });
14321
- const unreadableReask = result.admitted === void 0 ? void 0 : await reaskUnreadablePostSubmissionStatus(
14322
- result.admitted,
14323
- result.terminal,
14898
+ if (result.admitted === void 0) {
14899
+ await presentOriginalVolume(held, result.terminal, io);
14900
+ return result;
14901
+ }
14902
+ return continueAfterPostSubmissionGuards(
14903
+ result,
14904
+ result.admitted.role,
14324
14905
  env,
14325
- io
14906
+ io,
14907
+ held
14326
14908
  );
14327
- if (isUnreadableReaskExhausted(unreadableReask)) {
14328
- const terminal = result.terminal === void 0 ? void 0 : withUnsettledDirection(result.terminal);
14329
- await presentOriginalVolume(held, terminal, io, result.admitted?.runDirectory);
14330
- return terminal === void 0 ? result : { ...result, terminal };
14331
- }
14332
- if (unreadableReask !== void 0) return unreadableReask;
14333
- if (result.admitted !== void 0 && AUDITED_ROLES.has(result.admitted.role) && result.terminal?.roleOutcome.kind === "accepted") {
14334
- return auditSubmittedRole(result, env, io);
14335
- }
14336
- await presentOriginalVolume(held, result.terminal, io, result.admitted?.runDirectory);
14337
- return result;
14338
14909
  };
14339
14910
  let binding;
14340
14911
  try {
@@ -14367,7 +14938,7 @@ async function queueConclusionFromChild(child, env, io) {
14367
14938
  return { stop: { exitCode: 0, ...terminal === void 0 ? {} : { terminal } } };
14368
14939
  }
14369
14940
  let current = child;
14370
- let budgetEnv = { ...env, unreadableReasksSpent: 0 };
14941
+ let budgetEnv = envForCourtContinue(env);
14371
14942
  for (; ; ) {
14372
14943
  const terminal = await trySettlePublicSeat(
14373
14944
  current,
@@ -14438,7 +15009,7 @@ async function continueParentAfterChild(parentRunId, child, env, io) {
14438
15009
  return runPublicInstructionSeatResume({
14439
15010
  runId: parentRunId,
14440
15011
  summons: { instruction: readableGateItem(latestQueuePayload(resolved.terminal)) }
14441
- }, { ...env, unreadableReasksSpent: 0 }, io);
15012
+ }, envForCourtContinue(env), io);
14442
15013
  }
14443
15014
  const result = await dispatchAdmitted(admitted, env, { ...io, omitFailureStderrDiagnostic: true });
14444
15015
  showResumeErrorPointer(io, result.exitCode, result.terminal);
@@ -14468,6 +15039,7 @@ async function officerPassedCurrentSubmission(input) {
14468
15039
  return latestQueueStatus(terminal) === "converged";
14469
15040
  }
14470
15041
  async function auditSubmittedRole(turn, env, io, resumedOfficer, passedReceipt) {
15042
+ env = withoutSoftTicketReaskTurn(env);
14471
15043
  const admitted = turn.admitted;
14472
15044
  if (admitted === void 0 || !AUDITED_ROLES.has(admitted.role) || turn.terminal?.roleOutcome.kind !== "accepted") return turn;
14473
15045
  const accepted = turn.terminal.roleOutcome.payloads?.at(-1);
@@ -14501,10 +15073,10 @@ async function auditSubmittedRole(turn, env, io, resumedOfficer, passedReceipt)
14501
15073
  await presentTerminal(turn.terminal, { ...io, omitFailureStderrDiagnostic: true }, admitted.runDirectory);
14502
15074
  return turn;
14503
15075
  }
14504
- const rows = await readRecordedSubmissionRows(admitted.projectRoot, admitted.runId, env.home);
14505
- const acceptedRow = [...rows].reverse().find((row) => row.role === admitted.role && row.kind === "accepted");
14506
- const toolCallId = acceptedRow?.toolCallId;
14507
- if (toolCallId === void 0) throw new Error("accepted submission has no tool call identity");
15076
+ const toolCallId = turn.terminal.submissionToolCallId;
15077
+ if (toolCallId === void 0 || toolCallId.length === 0) {
15078
+ throw new Error("accepted submission has no tool call identity");
15079
+ }
14508
15080
  const sessionFile = env.principalAuthority.decode(admitted.principal).sessionFile;
14509
15081
  const entries = admitted.role === "doctor" ? await readBoundSessionEntries(sessionFile) : [];
14510
15082
  const context = {
@@ -14570,7 +15142,7 @@ async function auditSubmittedRole(turn, env, io, resumedOfficer, passedReceipt)
14570
15142
  return runPublicInstructionSeatResume({
14571
15143
  runId: admitted.runId,
14572
15144
  summons: { instruction: readableGateItem(decision.receipt ?? decision.violations) }
14573
- }, { ...env, unreadableReasksSpent: 0 }, io);
15145
+ }, envForCourtContinue(env), io);
14574
15146
  }
14575
15147
  if (decision.status === "received") {
14576
15148
  if (lastSummon?.terminal === void 0) {
@@ -14670,7 +15242,7 @@ async function auditSubmittedRole(turn, env, io, resumedOfficer, passedReceipt)
14670
15242
  return runPublicInstructionSeatResume({
14671
15243
  runId: admitted.runId,
14672
15244
  summons: { instruction: readableGateItem(chain.passes.at(-1)?.receipt) }
14673
- }, { ...env, unreadableReasksSpent: 0 }, io);
15245
+ }, envForCourtContinue(env), io);
14674
15246
  }
14675
15247
  if (admitted.role === "secretariat") {
14676
15248
  const pass = chain.passes.at(-1);
@@ -14699,7 +15271,10 @@ var AUDITED_ROLES, SECRETARIAT_STATUS_REASK, WORKER_ROUTING_STATUSES, WORKER_STA
14699
15271
  var init_instruction_seat_run = __esm({
14700
15272
  "src/public-cli/instruction-seat-run.ts"() {
14701
15273
  "use strict";
15274
+ init_report_ticket_tool();
14702
15275
  init_role_run_placement();
15276
+ init_role_run_relocation();
15277
+ init_session_opening_materials();
14703
15278
  init_archivist_record_pointer();
14704
15279
  init_doctor_auditor();
14705
15280
  init_gatekeeper_role();
@@ -15386,7 +15961,7 @@ var init_analyst_gate_cycles_read = __esm({
15386
15961
 
15387
15962
  // src/analyst-ledger.ts
15388
15963
  import { readdir as readdir3 } from "node:fs/promises";
15389
- import { basename as basename11, join as join25 } from "node:path";
15964
+ import { basename as basename12, join as join25 } from "node:path";
15390
15965
  async function readExistingRunLifecycleState(runDirectory) {
15391
15966
  return (await readRoleRunIdentity(runDirectory))?.state;
15392
15967
  }
@@ -15738,7 +16313,7 @@ async function scanAnalystIssueRuns(input) {
15738
16313
  throw error;
15739
16314
  }
15740
16315
  for (const runDirectory of runDirectories) {
15741
- const runName = basename11(runDirectory);
16316
+ const runName = basename12(runDirectory);
15742
16317
  const parsed = parseRunLeaf(runName);
15743
16318
  if (parsed === void 0) continue;
15744
16319
  let scopeFields;
@@ -16723,7 +17298,7 @@ var init_analyst_model_groups = __esm({
16723
17298
 
16724
17299
  // src/analyst-entry.ts
16725
17300
  import { readFile as readFile13 } from "node:fs/promises";
16726
- import { Type as Type16 } from "typebox";
17301
+ import { Type as Type17 } from "typebox";
16727
17302
  function cachedPageMatchesRequestedScope(page, input) {
16728
17303
  if (page.bookKey !== input.bookKey) return false;
16729
17304
  const requestedTicket = input.ticketNumber ?? input.issueNumber;
@@ -16928,16 +17503,16 @@ var init_analyst_entry = __esm({
16928
17503
  }
16929
17504
  }
16930
17505
  };
16931
- analystSweepModeInputSchema = Type16.Object(
17506
+ analystSweepModeInputSchema = Type17.Object(
16932
17507
  {
16933
- mode: Type16.Literal("sweep"),
16934
- mergedPullRequests: Type16.Array(
16935
- Type16.Object(
17508
+ mode: Type17.Literal("sweep"),
17509
+ mergedPullRequests: Type17.Array(
17510
+ Type17.Object(
16936
17511
  {
16937
- projectRoot: Type16.String(),
17512
+ projectRoot: Type17.String(),
16938
17513
  /** 排除后改动行数 — omit or 0 → typed 空缺; finite ≥ 0 only. */
16939
- changedLines: Type16.Optional(
16940
- Type16.Number({ minimum: 0, maximum: Number.MAX_VALUE })
17514
+ changedLines: Type17.Optional(
17515
+ Type17.Number({ minimum: 0, maximum: Number.MAX_VALUE })
16941
17516
  )
16942
17517
  }
16943
17518
  )
@@ -18030,7 +18605,7 @@ __export(public_role_summons_exports, {
18030
18605
  summonPublicRole: () => summonPublicRole
18031
18606
  });
18032
18607
  import { execFile as execFile3 } from "node:child_process";
18033
- import { existsSync as existsSync9 } from "node:fs";
18608
+ import { existsSync as existsSync13 } from "node:fs";
18034
18609
  import { realpath as realpath6 } from "node:fs/promises";
18035
18610
  import { join as join27 } from "node:path";
18036
18611
  import { promisify as promisify3 } from "node:util";
@@ -18056,7 +18631,7 @@ function parentDir(path) {
18056
18631
  function walkPackageRoot(start) {
18057
18632
  let dir = start;
18058
18633
  for (let i = 0; i < 12; i += 1) {
18059
- if (existsSync9(join27(dir, "package.json")) && existsSync9(join27(dir, "souls"))) {
18634
+ if (existsSync13(join27(dir, "package.json")) && existsSync13(join27(dir, "souls"))) {
18060
18635
  return dir;
18061
18636
  }
18062
18637
  const parent = parentDir(dir);
@@ -18724,6 +19299,24 @@ function rewriteRunDirectoryPathFields(record, fields, oldRunDirectory, newRunDi
18724
19299
  { oldRunDirectory, newRunDirectory }
18725
19300
  ]);
18726
19301
  }
19302
+ function rewritePrincipalSessionPaths(principal, oldRunDirectory, newRunDirectory) {
19303
+ rewriteRunDirectoryPathFields(
19304
+ principal,
19305
+ PRINCIPAL_SESSION_PATH_FIELDS,
19306
+ oldRunDirectory,
19307
+ newRunDirectory
19308
+ );
19309
+ }
19310
+ function projectTurnRequestLiveRunDirectory(request, newRunDirectory) {
19311
+ const old = request.runDirectory;
19312
+ if (old === newRunDirectory) return;
19313
+ request.runDirectory = newRunDirectory;
19314
+ rewritePrincipalSessionPaths(
19315
+ request.principal,
19316
+ old,
19317
+ newRunDirectory
19318
+ );
19319
+ }
18727
19320
  function rewriteRunDirectoryPathFieldsAgainstRewrites(record, fields, rewrites) {
18728
19321
  for (const field of fields) {
18729
19322
  if (field in record) {
@@ -18748,12 +19341,12 @@ function rewriteAdmittedRoleRunPage(page, rewrites) {
18748
19341
  if (isRecord(page.principal)) {
18749
19342
  rewriteRunDirectoryPathFieldsAgainstRewrites(
18750
19343
  page.principal,
18751
- ["sessionDirectory", "sessionFile"],
19344
+ PRINCIPAL_SESSION_PATH_FIELDS,
18752
19345
  rewrites
18753
19346
  );
18754
19347
  }
18755
19348
  }
18756
- var ADMITTED_PAGE_FIELDS, SOURCE_RUN_LOCATOR_FIELDS;
19349
+ var ADMITTED_PAGE_FIELDS, PRINCIPAL_SESSION_PATH_FIELDS, SOURCE_RUN_LOCATOR_FIELDS;
18757
19350
  var init_role_run_relocation = __esm({
18758
19351
  "src/role-run-relocation.ts"() {
18759
19352
  "use strict";
@@ -18775,6 +19368,10 @@ var init_role_run_relocation = __esm({
18775
19368
  "mergerInputPath",
18776
19369
  "sourceRunPath"
18777
19370
  ];
19371
+ PRINCIPAL_SESSION_PATH_FIELDS = [
19372
+ "sessionDirectory",
19373
+ "sessionFile"
19374
+ ];
18778
19375
  SOURCE_RUN_LOCATOR_FIELDS = ["runDirectory"];
18779
19376
  }
18780
19377
  });
@@ -18805,7 +19402,7 @@ __export(run_lifecycle_exports, {
18805
19402
  writeRoleRunState: () => writeRoleRunState
18806
19403
  });
18807
19404
  import { chmod, lstat as lstat3, open as open2, readdir as readdir4, readFile as readFile15, unlink as unlink2 } from "node:fs/promises";
18808
- import { basename as basename12, join as join29 } from "node:path";
19405
+ import { basename as basename13, join as join29 } from "node:path";
18809
19406
  function buildAutoResumeContinuationPrompt() {
18810
19407
  return RESUME_TRANSPORT_ENVELOPE;
18811
19408
  }
@@ -19252,7 +19849,7 @@ async function findLatestRunIdForSeatTicket(input) {
19252
19849
  }
19253
19850
  let best;
19254
19851
  for (const runDirectory of runDirectories) {
19255
- const parsed = parseRunLeaf(basename12(runDirectory));
19852
+ const parsed = parseRunLeaf(basename13(runDirectory));
19256
19853
  if (parsed === void 0 || parsed.role !== input.role) continue;
19257
19854
  const runId = parsed.runId;
19258
19855
  const parentPath = await readRunParentPath(runDirectory);
@@ -19447,7 +20044,7 @@ async function loadResumableRunRecord(home, runId, authority) {
19447
20044
  );
19448
20045
  }
19449
20046
  }
19450
- const sourceRunLeaf = parseRunLeaf(basename12(sourceRunPath ?? ""));
20047
+ const sourceRunLeaf = parseRunLeaf(basename13(sourceRunPath ?? ""));
19451
20048
  const referencedRunId = sourceRun?.runId ?? sourceRunLeaf?.runId;
19452
20049
  const referencedRole = sourceRun?.role ?? sourceRunLeaf?.role;
19453
20050
  if (referencedRunId !== void 0 && referencedRunId !== "") {
@@ -19795,7 +20392,7 @@ var init_archivist_record_topology = __esm({
19795
20392
  });
19796
20393
 
19797
20394
  // src/pi/record-session-host.ts
19798
- import { existsSync as existsSync10 } from "node:fs";
20395
+ import { existsSync as existsSync14 } from "node:fs";
19799
20396
  import { SessionManager } from "@earendil-works/pi-coding-agent";
19800
20397
  var piRecordSessionHost;
19801
20398
  var init_record_session_host = __esm({
@@ -19817,7 +20414,7 @@ var init_record_session_host = __esm({
19817
20414
  const sessionFile = session.getSessionFile();
19818
20415
  return {
19819
20416
  session,
19820
- resumed: sessionFile !== void 0 && existsSync10(sessionFile)
20417
+ resumed: sessionFile !== void 0 && existsSync14(sessionFile)
19821
20418
  };
19822
20419
  },
19823
20420
  inMemoryRecordSession(cwd) {
@@ -19840,7 +20437,7 @@ __export(archivist_record_entry_exports, {
19840
20437
  });
19841
20438
  import {
19842
20439
  closeSync,
19843
- existsSync as existsSync11,
20440
+ existsSync as existsSync15,
19844
20441
  openSync,
19845
20442
  readdirSync as readdirSync3,
19846
20443
  readFileSync as readFileSync4,
@@ -20001,7 +20598,7 @@ function mostRecentNavigatorSessionFile(sessionDir, cwd) {
20001
20598
  }
20002
20599
  function resolveNavigatorNestContinuation(sessionDir, cwd) {
20003
20600
  const ledgerPath = currentSessionLedgerPath(sessionDir);
20004
- if (existsSync11(ledgerPath)) {
20601
+ if (existsSync15(ledgerPath)) {
20005
20602
  const recentFile = readCurrentSession(sessionDir);
20006
20603
  assertRecentFinalFileUnderSessionDir(sessionDir, recentFile);
20007
20604
  return recentFile;
@@ -20086,7 +20683,7 @@ function createRecordSessionOpen(options, host = piRecordSessionHost) {
20086
20683
  parentSession = parentFile;
20087
20684
  mayResumeSameNest = options.kind === WORKER_SUBMISSION_GATE_KIND;
20088
20685
  }
20089
- const nestAlreadyExists = existsSync11(sessionDir);
20686
+ const nestAlreadyExists = existsSync15(sessionDir);
20090
20687
  ensureRealDirectoryTree(ledgerHome, sessionDir);
20091
20688
  if (mayResumeSameNest && nestAlreadyExists) {
20092
20689
  if (options.kind === NAVIGATOR_RECORD_KIND) {
@@ -20111,7 +20708,7 @@ function createRecordSessionOpen(options, host = piRecordSessionHost) {
20111
20708
  });
20112
20709
  if (session.isPersisted()) {
20113
20710
  const file = session.getSessionFile();
20114
- if (file !== void 0 && !existsSync11(file)) {
20711
+ if (file !== void 0 && !existsSync15(file)) {
20115
20712
  const header = session.getHeader();
20116
20713
  if (header !== null && header.type === "session") {
20117
20714
  writeFileSync2(file, `${JSON.stringify(header)}
@@ -20159,12 +20756,12 @@ init_packaged_role_registry();
20159
20756
  init_activation_ledger_topology();
20160
20757
  import { resolve as resolve16 } from "node:path";
20161
20758
  import "@earendil-works/pi-coding-agent";
20162
- import { Type as Type17 } from "typebox";
20759
+ import { Type as Type18 } from "typebox";
20163
20760
 
20164
20761
  // src/navigator-public-session.ts
20165
20762
  init_host_session_record();
20166
- import { existsSync as existsSync12 } from "node:fs";
20167
- import { basename as basename13 } from "node:path";
20763
+ import { existsSync as existsSync16 } from "node:fs";
20764
+ import { basename as basename14 } from "node:path";
20168
20765
 
20169
20766
  // src/navigator-session-contracts.ts
20170
20767
  init_unknown_value();
@@ -20450,7 +21047,7 @@ async function resolveNavigatorLedgerHome(context) {
20450
21047
  }
20451
21048
  var NAVIGATOR_HOST_RUN_POINTER_ENTRY = "ak-navigator-host-run";
20452
21049
  function runIdFromNavigatorDirectory(runDirectory) {
20453
- const parsed = parseRunLeaf(basename13(runDirectory));
21050
+ const parsed = parseRunLeaf(basename14(runDirectory));
20454
21051
  if (parsed === void 0 || parsed.role !== "navigator") return void 0;
20455
21052
  return parsed.runId;
20456
21053
  }
@@ -20512,7 +21109,7 @@ function createNativeNavigatorSessionFactory(deps) {
20512
21109
  if (disposed) return;
20513
21110
  const resumeRunId = hostRunId;
20514
21111
  const workContextPath = navigatorWorkContextFile(sessionManager.getSessionDir());
20515
- const workContextLocator = existsSync12(workContextPath) ? workContextPath : void 0;
21112
+ const workContextLocator = existsSync16(workContextPath) ? workContextPath : void 0;
20516
21113
  const baseSummon = {
20517
21114
  role: "navigator",
20518
21115
  argv: [text],
@@ -20647,8 +21244,8 @@ function resolveNavigatorAuthorityMaterial(roleInput, fileAuthority) {
20647
21244
  return void 0;
20648
21245
  }
20649
21246
  var NAVIGATOR_TARGETS = PACKAGED_ROLE_REGISTRY.map(({ role, phases }) => ({ role, phases }));
20650
- var prepareSchema = Type17.Object({
20651
- prose: Type17.Optional(Type17.Unknown({
21247
+ var prepareSchema = Type18.Object({
21248
+ prose: Type18.Optional(Type18.Unknown({
20652
21249
  description: "\u6E38\u5955\u4F7F\u6563\u6587\u5EFA\u8BAE\uFF0C\u539F\u6837\u5448\u73B0\u3002\u4E0D\u8981\u6C42 candidates/next \u7ED3\u6784\u3002"
20653
21250
  }))
20654
21251
  }, { additionalProperties: true });
@@ -21187,24 +21784,25 @@ init_sitian_facade();
21187
21784
  init_host_session_record();
21188
21785
  init_submission_ledger();
21189
21786
  init_filed_submission();
21787
+ init_report_ticket_tool();
21190
21788
  import { randomUUID as randomUUID7 } from "node:crypto";
21191
21789
  import { writeSync as writeSync2 } from "node:fs";
21192
21790
  import { join as join33 } from "node:path";
21193
21791
  import { Value as Value3 } from "typebox/value";
21194
21792
 
21195
21793
  // src/activation-trace.ts
21196
- import { Type as Type18 } from "typebox";
21197
- var causeSchema = Type18.Object({
21198
- identity: Type18.String({ minLength: 1 }),
21199
- name: Type18.String({ minLength: 1 }),
21200
- message: Type18.String(),
21201
- evidenceId: Type18.Optional(Type18.String({ minLength: 1 }))
21794
+ import { Type as Type19 } from "typebox";
21795
+ var causeSchema = Type19.Object({
21796
+ identity: Type19.String({ minLength: 1 }),
21797
+ name: Type19.String({ minLength: 1 }),
21798
+ message: Type19.String(),
21799
+ evidenceId: Type19.Optional(Type19.String({ minLength: 1 }))
21202
21800
  }, { additionalProperties: false });
21203
- var activationTraceRecordSchema = Type18.Object({
21204
- role: Type18.String({ minLength: 1 }),
21205
- stageId: Type18.String({ pattern: "^[a-z][a-z0-9-]*$" }),
21206
- status: Type18.Literal("failed"),
21207
- timestamp: Type18.String({ format: "date-time" }),
21801
+ var activationTraceRecordSchema = Type19.Object({
21802
+ role: Type19.String({ minLength: 1 }),
21803
+ stageId: Type19.String({ pattern: "^[a-z][a-z0-9-]*$" }),
21804
+ status: Type19.Literal("failed"),
21805
+ timestamp: Type19.String({ format: "date-time" }),
21208
21806
  cause: causeSchema
21209
21807
  }, { additionalProperties: false });
21210
21808
  var activationCauseEvidence = 0;
@@ -21369,10 +21967,10 @@ init_engine_material();
21369
21967
  init_engine_detour();
21370
21968
  init_engine_detour_usage();
21371
21969
  init_run_terminal_artifacts();
21372
- import { Type as Type19 } from "typebox";
21373
- var engineDetourArgsSchema = Type19.Object(
21970
+ import { Type as Type20 } from "typebox";
21971
+ var engineDetourArgsSchema = Type20.Object(
21374
21972
  {
21375
- argv: Type19.Array(Type19.String({ minLength: 1 }), {
21973
+ argv: Type20.Array(Type20.String({ minLength: 1 }), {
21376
21974
  minItems: 1,
21377
21975
  description: "\u9996\u9879\u4E3A PATH \u4E2D\u7684\u53EF\u6267\u884C\u6587\u4EF6\uFF0C\u5176\u4F59\u9879\u4E3A\u53C2\u6570\u3002"
21378
21976
  })
@@ -21696,10 +22294,10 @@ init_run_ticket_number();
21696
22294
 
21697
22295
  // src/audited-run-identity.ts
21698
22296
  init_role_run_placement();
21699
- import { basename as basename14 } from "node:path";
22297
+ import { basename as basename15 } from "node:path";
21700
22298
  var AUDITED_RUN_IDENTITY_KIND = "audited-run-identity";
21701
22299
  function auditedRunIdentityFromDirectory(runDirectory) {
21702
- const parsed = parseRunLeaf(basename14(runDirectory));
22300
+ const parsed = parseRunLeaf(basename15(runDirectory));
21703
22301
  if (parsed === void 0) return void 0;
21704
22302
  return formatRunLeaf(parsed.runId, parsed.role);
21705
22303
  }
@@ -21921,7 +22519,7 @@ init_unknown_value();
21921
22519
  init_submission_errors();
21922
22520
  init_worker_submission_contracts();
21923
22521
  import { execFileSync as execFileSync3 } from "node:child_process";
21924
- import { existsSync as existsSync13, lstatSync as lstatSync3, readdirSync as readdirSync4, readFileSync as readFileSync5, rmdirSync, rmSync as rmSync3 } from "node:fs";
22522
+ import { existsSync as existsSync17, lstatSync as lstatSync3, readdirSync as readdirSync4, readFileSync as readFileSync5, rmdirSync, rmSync as rmSync3 } from "node:fs";
21925
22523
  import { resolve as resolve19 } from "node:path";
21926
22524
  var WORKER_SUBMISSION_GATE_RECORD_KIND = WORKER_SUBMISSION_GATE_KIND;
21927
22525
  var WORKER_COMMIT_BASELINE_ENTRY_TYPE = "commit-baseline";
@@ -21951,7 +22549,7 @@ function statusOf(error) {
21951
22549
  return typeof error === "object" && error !== null && "status" in error ? error.status : void 0;
21952
22550
  }
21953
22551
  function tryGetAll(file, key) {
21954
- if (!existsSync13(file)) return [];
22552
+ if (!existsSync17(file)) return [];
21955
22553
  try {
21956
22554
  const out = gitFile(file, ["--get-all", key]);
21957
22555
  return out.length === 0 ? [] : out.split("\n");
@@ -21961,7 +22559,7 @@ function tryGetAll(file, key) {
21961
22559
  }
21962
22560
  }
21963
22561
  function ownedHook(path) {
21964
- if (!existsSync13(path)) return false;
22562
+ if (!existsSync17(path)) return false;
21965
22563
  return readFileSync5(path, "utf8").includes(HOOK_MARKER);
21966
22564
  }
21967
22565
  function escapeGitConfigValueRegex(value) {
@@ -21988,11 +22586,11 @@ function rmOwnedDir(dir) {
21988
22586
  const hookPath = resolve19(dir, HOOK_FILE);
21989
22587
  if (!ownedHook(hookPath)) return;
21990
22588
  rmSync3(hookPath, { force: true });
21991
- if (existsSync13(dir) && readdirSync4(dir).length === 0) rmdirSync(dir);
22589
+ if (existsSync17(dir) && readdirSync4(dir).length === 0) rmdirSync(dir);
21992
22590
  }
21993
22591
  function linkedGitDirs(commonDir) {
21994
22592
  const root = resolve19(commonDir, "worktrees");
21995
- if (!existsSync13(root)) return [];
22593
+ if (!existsSync17(root)) return [];
21996
22594
  return readdirSync4(root).map((name) => resolve19(root, name)).filter((dir) => lstatSync3(dir).isDirectory());
21997
22595
  }
21998
22596
  function uninstallPackageWorkerHooks(cwd) {
@@ -22084,6 +22682,7 @@ function createWorkerSubmissionGate(options = {}) {
22084
22682
  let unfinishedReasonBounces = 0;
22085
22683
  let invocationScopeId;
22086
22684
  let record;
22685
+ let parentRef;
22087
22686
  let sessionParent;
22088
22687
  const explicitHome = typeof options.home === "string" && options.home.length > 0 ? options.home : void 0;
22089
22688
  const unfinishedReasonBounceLimit = deliveryLimitFromConfig(options.unfinishedReasonBounceLimit);
@@ -22095,6 +22694,20 @@ function createWorkerSubmissionGate(options = {}) {
22095
22694
  return null;
22096
22695
  }
22097
22696
  };
22697
+ const liveRecord = () => {
22698
+ if (record === void 0 || root === void 0 || parentRef === void 0) return record;
22699
+ const file = record.getSessionFile();
22700
+ if (file !== void 0 && existsSync17(file)) return record;
22701
+ const parentFile = parentRef.getSessionFile();
22702
+ if (parentFile === void 0 || parentFile.length === 0) return record;
22703
+ sessionParent = parentFile;
22704
+ record = createRecordSession({
22705
+ cwd: root,
22706
+ kind: WORKER_SUBMISSION_GATE_RECORD_KIND,
22707
+ parent: parentRef
22708
+ });
22709
+ return record;
22710
+ };
22098
22711
  const gateSitian = (cwd, payload) => {
22099
22712
  sitianReport({
22100
22713
  level: "event",
@@ -22111,6 +22724,7 @@ function createWorkerSubmissionGate(options = {}) {
22111
22724
  invocationScopeId = scope;
22112
22725
  uninstallPackageWorkerHooks(cwd);
22113
22726
  root = cwd;
22727
+ parentRef = parent;
22114
22728
  sessionParent = parent.getSessionFile();
22115
22729
  record = createRecordSession({
22116
22730
  cwd,
@@ -22139,9 +22753,10 @@ function createWorkerSubmissionGate(options = {}) {
22139
22753
  });
22140
22754
  },
22141
22755
  assertAcceptable(status, details) {
22756
+ const gateRecord = liveRecord();
22142
22757
  if (status === "unfinished" && !unfinishedReasonPresent(details)) {
22143
22758
  if (unfinishedReasonBounces < unfinishedReasonBounceLimit) {
22144
- record?.appendCustomEntry(WORKER_UNFINISHED_REASON_BOUNCE_ENTRY_TYPE, {
22759
+ gateRecord?.appendCustomEntry(WORKER_UNFINISHED_REASON_BOUNCE_ENTRY_TYPE, {
22145
22760
  version: 1,
22146
22761
  invocationScopeId
22147
22762
  });
@@ -22154,7 +22769,7 @@ function createWorkerSubmissionGate(options = {}) {
22154
22769
  const headMoved = now !== null && (baseline === null || now !== baseline);
22155
22770
  if (!headMoved && !reminded) {
22156
22771
  reminded = true;
22157
- record?.appendCustomEntry(WORKER_COMMIT_REMINDER_BOUNCE_ENTRY_TYPE, { version: 1 });
22772
+ gateRecord?.appendCustomEntry(WORKER_COMMIT_REMINDER_BOUNCE_ENTRY_TYPE, { version: 1 });
22158
22773
  gateSitian(root, {
22159
22774
  type: WORKER_COMMIT_REMINDER_BOUNCE_ENTRY_TYPE,
22160
22775
  version: 1
@@ -22168,7 +22783,7 @@ function createWorkerSubmissionGate(options = {}) {
22168
22783
  return;
22169
22784
  }
22170
22785
  prefixReminded = true;
22171
- record?.appendCustomEntry(WORKER_PREFIX_REMINDER_BOUNCE_ENTRY_TYPE, { version: 1 });
22786
+ gateRecord?.appendCustomEntry(WORKER_PREFIX_REMINDER_BOUNCE_ENTRY_TYPE, { version: 1 });
22172
22787
  gateSitian(root, {
22173
22788
  type: WORKER_PREFIX_REMINDER_BOUNCE_ENTRY_TYPE,
22174
22789
  version: 1
@@ -23634,6 +24249,10 @@ function createRoleRuntimeExtension(dependencies, deliveryRequestLimit) {
23634
24249
  }
23635
24250
  }
23636
24251
  await executeActivationStage(entry.role, activationStage(entry.role, activateByRole), { clock, writeTrace });
24252
+ registerReportTicketTool(roleHost);
24253
+ roleHost.setActiveTools([
24254
+ .../* @__PURE__ */ new Set([...roleHost.getActiveTools(), REPORT_TICKET_TOOL_NAME])
24255
+ ]);
23637
24256
  roleReferenceMaterials = await dependencies.loadRoleReferenceMaterials?.(entry.role) ?? "";
23638
24257
  if (!engineDetourRegistered) {
23639
24258
  engineDetourRegistered = registerEngineDetourTool(roleHost, hostActions);
@@ -23710,6 +24329,7 @@ import { createServer } from "node:net";
23710
24329
  import { dirname as dirname21 } from "node:path";
23711
24330
  import { fileURLToPath as fileURLToPath2 } from "node:url";
23712
24331
  init_role_activation_flags();
24332
+ init_role_run_relocation();
23713
24333
  init_submission_correctable_error();
23714
24334
  init_navigator_invocation_identity();
23715
24335
  init_serialize_thrown_value();
@@ -23795,11 +24415,11 @@ async function prepareRoleEnvelope(options) {
23795
24415
  }
23796
24416
  });
23797
24417
  };
24418
+ const mutableRequest = request;
23798
24419
  const context = {
23799
24420
  cwd: request.cwd,
23800
24421
  mode: "print",
23801
24422
  model: request.model === void 0 ? void 0 : { provider: request.model.provider },
23802
- runDirectory: request.runDirectory,
23803
24423
  ...request.courtAttemptId === void 0 ? {} : { courtAttemptId: request.courtAttemptId },
23804
24424
  ...request.invocationScopeId === void 0 ? {} : { invocationScopeId: request.invocationScopeId },
23805
24425
  ...request.host === void 0 || request.host.trim() === "" ? {} : { host: request.host.trim() },
@@ -23824,6 +24444,25 @@ async function prepareRoleEnvelope(options) {
23824
24444
  abort() {
23825
24445
  }
23826
24446
  };
24447
+ Object.defineProperty(context, "runDirectory", {
24448
+ configurable: true,
24449
+ enumerable: true,
24450
+ get() {
24451
+ return mutableRequest.runDirectory;
24452
+ },
24453
+ set(next) {
24454
+ if (typeof next !== "string" || next.trim() === "") return;
24455
+ if (mutableRequest.runDirectory === next) return;
24456
+ projectTurnRequestLiveRunDirectory(mutableRequest, next);
24457
+ sessionFile = sessionFileOf(next);
24458
+ if (typeof mutableRequest.principal.sessionDirectory !== "string") {
24459
+ mutableRequest.principal.sessionDirectory = sessionDirectoryOf(next);
24460
+ }
24461
+ if (typeof mutableRequest.principal.sessionFile !== "string") {
24462
+ mutableRequest.principal.sessionFile = sessionFile;
24463
+ }
24464
+ }
24465
+ });
23827
24466
  const bookCustomMessage = (customType, message) => {
23828
24467
  const payload = {
23829
24468
  ...message.content === void 0 ? {} : { content: message.content },
@@ -24152,7 +24791,7 @@ async function prepareRoleEnvelope(options) {
24152
24791
  });
24153
24792
  } catch (error) {
24154
24793
  await retainPackageFault({
24155
- runDirectory: request.runDirectory,
24794
+ runDirectory: mutableRequest.runDirectory,
24156
24795
  diagnostic: `relay close failed beside envelope shutdown: ${describeErrorIdentity(error)}`,
24157
24796
  error
24158
24797
  });
@@ -24285,165 +24924,16 @@ init_session_identity();
24285
24924
 
24286
24925
  // src/headless-host/role-turn-host.ts
24287
24926
  init_role_run_placement();
24927
+ init_external_host_turn_loop();
24928
+ init_run_lifecycle();
24929
+ init_settlement();
24288
24930
  import { spawn as spawn3, spawnSync as spawnSync3 } from "node:child_process";
24289
24931
  import { randomUUID as randomUUID9 } from "node:crypto";
24290
- import { existsSync as existsSync14 } from "node:fs";
24932
+ import { existsSync as existsSync18 } from "node:fs";
24291
24933
  import { mkdtemp, rm as rm2, writeFile as writeFile6 } from "node:fs/promises";
24292
24934
  import { tmpdir } from "node:os";
24293
24935
  import { dirname as dirname22, isAbsolute as isAbsolute11, join as join34, resolve as resolve20 } from "node:path";
24294
24936
 
24295
- // src/external-host-turn-loop.ts
24296
- init_settlement();
24297
- init_run_lifecycle();
24298
- init_receipt_delivery_policy();
24299
- init_sitian_facade();
24300
- init_submission_errors();
24301
- async function recordTurnDelivery(runDirectory, delivered, source) {
24302
- try {
24303
- reportRunRecord(runDirectory, "turn-delivery", {
24304
- systemPrompt: delivered.systemPrompt,
24305
- ...delivered.outputSchema === void 0 ? {} : { outputSchema: delivered.outputSchema }
24306
- }, source);
24307
- } catch (error) {
24308
- await retainPackageFault({
24309
- runDirectory,
24310
- diagnostic: `turn delivery record failed beside host start: ${describeErrorIdentity(error)}`,
24311
- error
24312
- });
24313
- }
24314
- }
24315
- function mergeRoleTurnAbortSignals(prepared, request) {
24316
- if (request === void 0) return prepared;
24317
- if (prepared === void 0) return request;
24318
- return AbortSignal.any([prepared, request]);
24319
- }
24320
- function isHostAbortedError(error) {
24321
- return typeof error === "object" && error !== null && error.code === "host-aborted";
24322
- }
24323
- function hostAbortedError(message = "host aborted") {
24324
- return Object.assign(new Error(message), { code: "host-aborted" });
24325
- }
24326
- function externalHostFailure(cause, name, code, details, diagnostic) {
24327
- return asFailure({
24328
- cause,
24329
- identity: { name, code },
24330
- ...diagnostic === void 0 ? {} : { diagnostic },
24331
- ...details === void 0 ? {} : { details }
24332
- });
24333
- }
24334
- function asFailure(knownFailure, stderr = "") {
24335
- return { code: null, stderr, timedOut: false, knownFailure };
24336
- }
24337
- async function settleHostAborted(prepared, sessionId) {
24338
- const closure = await prepared.closeRound();
24339
- if ("failure" in closure) return asFailure(closure.failure);
24340
- return asFailure({
24341
- cause: "session",
24342
- identity: { name: "HostAborted", code: "host-aborted" },
24343
- ...sessionId === void 0 ? {} : { details: { sessionId } }
24344
- });
24345
- }
24346
- async function driveExternalRoleTurnRounds(prepared, request, driver) {
24347
- let prompt = prepared.prompt;
24348
- const abortSignal = mergeRoleTurnAbortSignals(prepared.abortSignal, request.signal);
24349
- let result = { code: 0, stderr: "", timedOut: false };
24350
- const countedReaskLimit = deliveryLimitFromConfig(request.deliveryRequestLimit);
24351
- const exemptReminders = /* @__PURE__ */ new Set();
24352
- let countedReasks = 0;
24353
- for (let attempt = 0; ; attempt += 1) {
24354
- if (abortSignal?.aborted) return settleHostAborted(prepared, driver.currentSessionId());
24355
- let round;
24356
- try {
24357
- round = await driver.runRound({ prompt, abortSignal, attempt });
24358
- } catch (error) {
24359
- if (isHostAbortedError(error)) return settleHostAborted(prepared, driver.currentSessionId());
24360
- throw error;
24361
- }
24362
- if (round.status === "terminal") return round.result;
24363
- result = {
24364
- code: round.code !== void 0 ? round.code : 0,
24365
- stderr: round.stderr ?? "",
24366
- timedOut: round.timedOut === true,
24367
- ...round.signal === void 0 ? {} : { signal: round.signal }
24368
- };
24369
- let closure;
24370
- try {
24371
- closure = await prepared.closeRound();
24372
- } catch (error) {
24373
- await retainPackageFault({
24374
- runDirectory: request.runDirectory,
24375
- diagnostic: `round closure failed beside host terminal: ${describeErrorIdentity(error)}`,
24376
- error
24377
- });
24378
- return result.code === 0 && !result.timedOut && result.signal === void 0 ? { ...result, knownFailure: projectThrownFailureLeaf(error) } : result;
24379
- }
24380
- if (closure.accepted) {
24381
- try {
24382
- await driver.afterAccepted?.();
24383
- } catch (error) {
24384
- await retainPackageFault({
24385
- runDirectory: request.runDirectory,
24386
- diagnostic: `post-acceptance close failed beside host terminal: ${describeErrorIdentity(error)}`,
24387
- error
24388
- });
24389
- }
24390
- return result;
24391
- }
24392
- if ("failure" in closure) {
24393
- await retainPackageFault({
24394
- runDirectory: request.runDirectory,
24395
- diagnostic: `round closure failed beside host terminal: ${JSON.stringify(closure.failure)}`
24396
- });
24397
- return result.code === 0 && !result.timedOut && result.signal === void 0 ? { ...result, knownFailure: closure.failure } : result;
24398
- }
24399
- if (result.code !== 0 || result.signal !== void 0 || result.timedOut) return result;
24400
- const reminderCode = closure.retry.code;
24401
- const exempt = isOneShotWorkerReminderCode(reminderCode) && !exemptReminders.has(reminderCode);
24402
- if (exempt) exemptReminders.add(reminderCode);
24403
- else {
24404
- countedReasks += 1;
24405
- if (countedReasks > countedReaskLimit) {
24406
- await retainPackageFault({
24407
- runDirectory: request.runDirectory,
24408
- diagnostic: `${driver.roundLimitName}: round-retry-limit`
24409
- });
24410
- return result;
24411
- }
24412
- }
24413
- prompt = closure.retry.message;
24414
- driver.afterRetry?.();
24415
- }
24416
- }
24417
- async function disposeExternalRoleTurn(prepared, request, outcome) {
24418
- try {
24419
- await prepared.dispose?.();
24420
- } catch (error) {
24421
- await retainPackageFault({
24422
- runDirectory: request.runDirectory,
24423
- diagnostic: `required envelope shutdown failed beside host terminal: ${describeErrorIdentity(error)}`,
24424
- error
24425
- });
24426
- if (outcome.code === 0 && !outcome.timedOut && outcome.signal === void 0 && outcome.knownFailure === void 0) {
24427
- return { ...outcome, knownFailure: projectThrownFailureLeaf(error) };
24428
- }
24429
- }
24430
- return outcome;
24431
- }
24432
- function createSerializedRoleTurnHost(execute) {
24433
- let serial = Promise.resolve();
24434
- return {
24435
- executeTurn(request) {
24436
- const execution = serial.then(() => execute(request));
24437
- serial = execution.then(() => void 0, () => void 0);
24438
- return execution;
24439
- }
24440
- };
24441
- }
24442
-
24443
- // src/headless-host/role-turn-host.ts
24444
- init_run_lifecycle();
24445
- init_settlement();
24446
-
24447
24937
  // src/agent-start-materials.ts
24448
24938
  function renderAgentStartMaterials(body, materials) {
24449
24939
  if (materials.length === 0) return body;
@@ -24829,7 +25319,7 @@ function formatCodexFailurePayload(payload) {
24829
25319
  function cwdIsGitWorkTree(cwd) {
24830
25320
  let dir = cwd;
24831
25321
  for (; ; ) {
24832
- if (existsSync14(join34(dir, ".git"))) return true;
25322
+ if (existsSync18(join34(dir, ".git"))) return true;
24833
25323
  const parent = dirname22(dir);
24834
25324
  if (parent === dir) return false;
24835
25325
  dir = parent;
@@ -25046,7 +25536,7 @@ function createHeadlessRoleTurnHost(config) {
25046
25536
  await config.sessionIdentity.bind(request.principal, sessionId);
25047
25537
  }
25048
25538
  const env = { ...process.env, ...config.env ?? {} };
25049
- const sessionParent = config.sessionIdentity.resolveSessionFile(request.principal);
25539
+ const liveSessionParent = () => config.sessionIdentity.resolveSessionFile(request.principal);
25050
25540
  const inputsDirectory = await mkdtemp(join34(tmpdir(), "ak-role-headless-"));
25051
25541
  const systemPromptPath = join34(inputsDirectory, "system-prompt.txt");
25052
25542
  let mcpConfigPath;
@@ -25077,8 +25567,7 @@ function createHeadlessRoleTurnHost(config) {
25077
25567
  try {
25078
25568
  await rm2(inputsDirectory, { recursive: true, force: true });
25079
25569
  } catch (cleanupError) {
25080
- await retainPackageFault({
25081
- runDirectory: request.runDirectory,
25570
+ await retainPackageFaultBesideLivePlacement(request, {
25082
25571
  diagnostic: `headless turn inputs cleanup failed beside setup failure: ${describeErrorIdentity(cleanupError)}`,
25083
25572
  error: cleanupError
25084
25573
  });
@@ -25127,11 +25616,11 @@ function createHeadlessRoleTurnHost(config) {
25127
25616
  host: config.hostName,
25128
25617
  sessionId,
25129
25618
  cwd: request.cwd,
25130
- sessionParent,
25619
+ sessionParent: liveSessionParent(),
25131
25620
  home: request.home
25132
25621
  }) !== void 0;
25133
25622
  }
25134
- await recordTurnDelivery(request.runDirectory, {
25623
+ await recordTurnDelivery(await syncTurnRequestLivePlacement(request), {
25135
25624
  systemPrompt,
25136
25625
  ...startedWithSchema === void 0 ? {} : { outputSchema: startedWithSchema }
25137
25626
  }, "headless-host");
@@ -25157,7 +25646,7 @@ function createHeadlessRoleTurnHost(config) {
25157
25646
  codexObserver?.observe(event);
25158
25647
  if (!codex && typeof event === "object" && event !== null && "session_id" in event && typeof event.session_id === "string" && event.session_id !== "" && event.session_id !== sessionId) {
25159
25648
  sessionId = event.session_id;
25160
- recordNativeSessionPointer({ host: config.hostName, sessionId, cwd: request.cwd, sessionParent, home: request.home });
25649
+ recordNativeSessionPointer({ host: config.hostName, sessionId, cwd: request.cwd, sessionParent: liveSessionParent(), home: request.home });
25161
25650
  }
25162
25651
  if (codex && !codexIdObserved) {
25163
25652
  const tid = codexObserver?.result().threadId;
@@ -25167,7 +25656,7 @@ function createHeadlessRoleTurnHost(config) {
25167
25656
  host: config.hostName,
25168
25657
  sessionId: tid,
25169
25658
  cwd: request.cwd,
25170
- sessionParent,
25659
+ sessionParent: liveSessionParent(),
25171
25660
  home: request.home
25172
25661
  }) !== void 0;
25173
25662
  }
@@ -25178,7 +25667,7 @@ function createHeadlessRoleTurnHost(config) {
25178
25667
  exitedSessionId = roundSessionId;
25179
25668
  if (codex && roundSessionId !== void 0 && roundSessionId !== "" && !pointerRecorded) {
25180
25669
  try {
25181
- recordNativeSessionPointer({ host: config.hostName, sessionId: roundSessionId, cwd: request.cwd, sessionParent, home: request.home });
25670
+ recordNativeSessionPointer({ host: config.hostName, sessionId: roundSessionId, cwd: request.cwd, sessionParent: liveSessionParent(), home: request.home });
25182
25671
  } catch (error) {
25183
25672
  spawned.packageErrors = [...spawned.packageErrors, error];
25184
25673
  }
@@ -25195,16 +25684,14 @@ function createHeadlessRoleTurnHost(config) {
25195
25684
  };
25196
25685
  }
25197
25686
  for (const error of spawned.packageErrors) {
25198
- await retainPackageFault({
25199
- runDirectory: request.runDirectory,
25687
+ await retainPackageFaultBesideLivePlacement(request, {
25200
25688
  diagnostic: `headless transport handling failed beside host terminal: ${describeErrorIdentity(error)}`,
25201
25689
  error
25202
25690
  });
25203
25691
  }
25204
25692
  try {
25205
25693
  const noteBeside = async (error, what) => {
25206
- await retainPackageFault({
25207
- runDirectory: request.runDirectory,
25694
+ await retainPackageFaultBesideLivePlacement(request, {
25208
25695
  diagnostic: `${what}: ${describeErrorIdentity(error)}`,
25209
25696
  error
25210
25697
  });
@@ -25272,8 +25759,7 @@ function createHeadlessRoleTurnHost(config) {
25272
25759
  }
25273
25760
  return deliveredFromSpawned(spawned);
25274
25761
  } catch (error) {
25275
- await retainPackageFault({
25276
- runDirectory: request.runDirectory,
25762
+ await retainPackageFaultBesideLivePlacement(request, {
25277
25763
  diagnostic: `required turn handling failed beside host terminal: ${describeErrorIdentity(error)}`,
25278
25764
  error
25279
25765
  });
@@ -25285,27 +25771,35 @@ function createHeadlessRoleTurnHost(config) {
25285
25771
  }
25286
25772
  });
25287
25773
  } finally {
25774
+ const live = await trySyncTurnRequestLivePlacement(request);
25775
+ const liveRunDirectory = "runDirectory" in live ? live.runDirectory : void 0;
25776
+ if (liveRunDirectory === void 0 && "resolveError" in live) {
25777
+ await retainPackageFaultBesideLivePlacement(request, {
25778
+ diagnostic: `headless cleanup live path resolve failed beside host terminal: ${describeErrorIdentity(live.resolveError)}`,
25779
+ error: live.resolveError
25780
+ });
25781
+ }
25288
25782
  try {
25289
25783
  await rm2(inputsDirectory, { recursive: true, force: true });
25290
25784
  } catch (error) {
25291
- await retainPackageFault({
25292
- runDirectory: request.runDirectory,
25785
+ await retainPackageFaultBesideLivePlacement(request, {
25293
25786
  diagnostic: `headless turn inputs cleanup failed beside host terminal: ${describeErrorIdentity(error)}`,
25294
25787
  error
25295
25788
  });
25296
25789
  }
25297
25790
  try {
25298
- if (exitedSessionId !== void 0 && exitedSessionId !== "") copyAndRecordHostDossier({
25299
- host: config.hostName,
25300
- sessionId: exitedSessionId,
25301
- cwd: request.cwd,
25302
- sessionDirectory: sessionDirectoryOf(request.runDirectory),
25303
- sessionParent,
25304
- ...request.home !== void 0 ? { home: request.home } : {}
25305
- });
25791
+ if (exitedSessionId !== void 0 && exitedSessionId !== "" && liveRunDirectory !== void 0) {
25792
+ copyAndRecordHostDossier({
25793
+ host: config.hostName,
25794
+ sessionId: exitedSessionId,
25795
+ cwd: request.cwd,
25796
+ sessionDirectory: sessionDirectoryOf(liveRunDirectory),
25797
+ sessionParent: sessionFileOf(liveRunDirectory),
25798
+ ...request.home !== void 0 ? { home: request.home } : {}
25799
+ });
25800
+ }
25306
25801
  } catch (error) {
25307
- await retainPackageFault({
25308
- runDirectory: request.runDirectory,
25802
+ await retainPackageFaultBesideLivePlacement(request, {
25309
25803
  diagnostic: `host dossier copy failed beside host terminal: ${describeErrorIdentity(error)}`,
25310
25804
  error
25311
25805
  });