@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
@@ -157,6 +157,7 @@ __export(activation_ledger_topology_exports, {
157
157
  physicallyContainedIn: () => physicallyContainedIn,
158
158
  resolveActivationLedgerHome: () => resolveActivationLedgerHome,
159
159
  resolveActivationLedgerHomeForPath: () => resolveActivationLedgerHomeForPath,
160
+ tryBookKeyFromAkRolesPath: () => tryBookKeyFromAkRolesPath,
160
161
  tryHomeFromAkRolesPath: () => tryHomeFromAkRolesPath
161
162
  });
162
163
  import {
@@ -178,6 +179,17 @@ function tryHomeFromAkRolesPath(path) {
178
179
  }
179
180
  return path.slice(0, match.index);
180
181
  }
182
+ function tryBookKeyFromAkRolesPath(path) {
183
+ const home = tryHomeFromAkRolesPath(path);
184
+ if (home === void 0 || home.length === 0) return void 0;
185
+ const booksRoot = join2(resolveActivationLedgerHome(home), "books");
186
+ const rel = relative(booksRoot, resolve(path));
187
+ if (rel === "" || rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute(rel)) {
188
+ return void 0;
189
+ }
190
+ const bookKey = rel.split(sep)[0];
191
+ return bookKey === void 0 || bookKey === "" ? void 0 : bookKey;
192
+ }
181
193
  function homeFromRunDirectory(runDirectory) {
182
194
  const home = tryHomeFromAkRolesPath(runDirectory);
183
195
  if (home === void 0 || home.length === 0) {
@@ -1149,8 +1161,7 @@ function roleRunPlacement(ledgerHome, input) {
1149
1161
  return {
1150
1162
  runDirectory,
1151
1163
  sessionDirectory,
1152
- sessionFile: sessionFileIn(sessionDirectory),
1153
- attachmentsDirectory: join6(runDirectory, "attachments")
1164
+ sessionFile: sessionFileIn(sessionDirectory)
1154
1165
  };
1155
1166
  }
1156
1167
  function isUnboundRunDirectory(runDirectory) {
@@ -7039,15 +7050,9 @@ async function relocateAdmittedRunToTicket(admitted, authority, heldLease) {
7039
7050
  }
7040
7051
  await rename(oldRunDirectory, target.runDirectory);
7041
7052
  heldLease?.relocate(target.runDirectory);
7042
- const admittedRecord = admitted;
7043
- rewriteRunDirectoryPathFields(
7044
- admittedRecord,
7045
- [
7046
- "runDirectory",
7047
- "mergerInputPath"
7048
- ],
7049
- oldRunDirectory,
7050
- target.runDirectory
7053
+ rewriteAdmittedRoleRunPage(
7054
+ admitted,
7055
+ [{ oldRunDirectory, newRunDirectory: target.runDirectory }]
7051
7056
  );
7052
7057
  admitted.principal = principal;
7053
7058
  renderCurrentSync(target.runDirectory);
@@ -7678,7 +7683,6 @@ async function placeRoleAdmission(options) {
7678
7683
  sessionDirectory,
7679
7684
  sessionFile,
7680
7685
  runDirectory,
7681
- attachmentsDirectory,
7682
7686
  ledgerHome,
7683
7687
  bookKey
7684
7688
  } = issueAdmissionPlacement(options.principalAuthority, {
@@ -7699,7 +7703,6 @@ async function placeRoleAdmission(options) {
7699
7703
  sessionDirectory,
7700
7704
  sessionFile,
7701
7705
  attachments,
7702
- attachmentsDirectory,
7703
7706
  ledgerHome,
7704
7707
  ticketFields
7705
7708
  };
@@ -8558,19 +8561,24 @@ function roleOutcomeFromRows(role, rows) {
8558
8561
  if (terminal.length === 0) return void 0;
8559
8562
  const payloads = mine.map((row) => row.accepted);
8560
8563
  const latest = terminal[terminal.length - 1];
8564
+ const submissionToolCallId = typeof latest.toolCallId === "string" && latest.toolCallId.length > 0 ? latest.toolCallId : void 0;
8565
+ const belonging = submissionToolCallId === void 0 ? {} : { submissionToolCallId };
8561
8566
  if (latest.kind === "audit-escalation") {
8562
8567
  return {
8563
- kind: "audit_escalation",
8564
- role,
8565
- status: "audit_escalation",
8566
- payloads,
8567
- ...Object.hasOwn(latest, "auditReceipt") ? { decisiveFacts: {
8568
- auditEscalationReceipt: latest.auditReceipt,
8569
- ...Object.hasOwn(latest, "auditOfficer") ? { auditEscalationOfficer: latest.auditOfficer } : {}
8570
- } } : {}
8568
+ outcome: {
8569
+ kind: "audit_escalation",
8570
+ role,
8571
+ status: "audit_escalation",
8572
+ payloads,
8573
+ ...Object.hasOwn(latest, "auditReceipt") ? { decisiveFacts: {
8574
+ auditEscalationReceipt: latest.auditReceipt,
8575
+ ...Object.hasOwn(latest, "auditOfficer") ? { auditEscalationOfficer: latest.auditOfficer } : {}
8576
+ } } : {}
8577
+ },
8578
+ ...belonging
8571
8579
  };
8572
8580
  }
8573
- return { kind: "accepted", role, payloads };
8581
+ return { outcome: { kind: "accepted", role, payloads }, ...belonging };
8574
8582
  }
8575
8583
  async function sealedLedgerOutcome(admitted, role, scope) {
8576
8584
  const home = sealedLedgerHome(admitted);
@@ -9205,8 +9213,8 @@ function entriesOf(read) {
9205
9213
  }
9206
9214
  async function settleSealedSeat(admitted, authority, scope, options) {
9207
9215
  const coordinates = coordinatesFromAdmitted(authority, admitted);
9208
- const roleOutcome = await sealedLedgerOutcome(admitted, admitted.role, scope);
9209
- if (roleOutcome === void 0 || options.acceptedOnly && roleOutcome.kind !== "accepted") {
9216
+ const settled = await sealedLedgerOutcome(admitted, admitted.role, scope);
9217
+ if (settled === void 0 || options.acceptedOnly && settled.outcome.kind !== "accepted") {
9210
9218
  return void 0;
9211
9219
  }
9212
9220
  const read = await readLawfulSettlementEntries(coordinates.sessionFile);
@@ -9217,15 +9225,23 @@ async function settleSealedSeat(admitted, authority, scope, options) {
9217
9225
  `session read failed beside lawful terminal: ${describeErrorIdentity(read.error)}`
9218
9226
  );
9219
9227
  }
9220
- return finishLawfulSeat(admitted, coordinates, entriesOf(read), roleOutcome, scope);
9228
+ return finishLawfulSeat(
9229
+ admitted,
9230
+ coordinates,
9231
+ entriesOf(read),
9232
+ settled.outcome,
9233
+ scope,
9234
+ settled.submissionToolCallId
9235
+ );
9221
9236
  }
9222
- async function finishLawfulSeat(admitted, coordinates, entries, roleOutcome, scope) {
9237
+ async function finishLawfulSeat(admitted, coordinates, entries, roleOutcome, scope, submissionToolCallId) {
9223
9238
  const artifacts = scope?.previewOnly === true ? [] : await publishDeclaredSeatTerminal(admitted, roleOutcome, coordinates, entries, scope);
9224
9239
  const terminal = await attachEngineDetourToolUsage({
9225
9240
  roleOutcome,
9226
9241
  navigator: extractNavigatorFact(entries),
9227
9242
  artifacts,
9228
- runId: admitted.runId
9243
+ runId: admitted.runId,
9244
+ ...submissionToolCallId === void 0 || submissionToolCallId.length === 0 ? {} : { submissionToolCallId }
9229
9245
  }, coordinates.sessionDirectory, detourUsageContext(admitted, scope));
9230
9246
  return attachRecordedSubmissions(admitted, terminal, scope);
9231
9247
  }
@@ -9577,6 +9593,242 @@ var init_settlement = __esm({
9577
9593
  }
9578
9594
  });
9579
9595
 
9596
+ // src/external-host-turn-loop.ts
9597
+ import { existsSync as existsSync4 } from "node:fs";
9598
+ import { basename as basename8 } from "node:path";
9599
+ async function resolveLiveRunDirectoryPath(recordedPath, home) {
9600
+ if (existsSync4(recordedPath)) return recordedPath;
9601
+ const parsed = parseRunLeaf(basename8(recordedPath));
9602
+ const bookKey = tryBookKeyFromAkRolesPath(recordedPath);
9603
+ if (parsed === void 0 || bookKey === void 0) return void 0;
9604
+ return await findRunDirectoryById(
9605
+ home,
9606
+ parsed.runId,
9607
+ bookKey,
9608
+ parsed.role
9609
+ );
9610
+ }
9611
+ async function syncTurnRequestLivePlacement(request) {
9612
+ const live = await resolveLiveRunDirectoryPath(request.runDirectory, request.home);
9613
+ if (live === void 0) {
9614
+ const parsed = parseRunLeaf(basename8(request.runDirectory));
9615
+ throw new Error(
9616
+ `admitted run ${parsed?.runId ?? "(unparseable)"} missing after host turn; not found under ${request.home}`
9617
+ );
9618
+ }
9619
+ if (live !== request.runDirectory) {
9620
+ projectTurnRequestLiveRunDirectory(
9621
+ request,
9622
+ live
9623
+ );
9624
+ }
9625
+ return live;
9626
+ }
9627
+ async function trySyncTurnRequestLivePlacement(request) {
9628
+ try {
9629
+ return { runDirectory: await syncTurnRequestLivePlacement(request) };
9630
+ } catch (resolveError) {
9631
+ return { resolveError };
9632
+ }
9633
+ }
9634
+ async function retainPackageFaultBesideLivePlacement(request, input) {
9635
+ const live = await trySyncTurnRequestLivePlacement(request);
9636
+ if ("resolveError" in live) {
9637
+ const resolveDiagnostic = `live run path resolve failed beside fault: ${describeErrorIdentity(live.resolveError)}`;
9638
+ try {
9639
+ process.stderr.write(`${input.diagnostic}
9640
+ `);
9641
+ process.stderr.write(`${resolveDiagnostic}
9642
+ `);
9643
+ } catch {
9644
+ }
9645
+ return;
9646
+ }
9647
+ await retainPackageFault({
9648
+ runDirectory: live.runDirectory,
9649
+ diagnostic: input.diagnostic,
9650
+ ...Object.hasOwn(input, "error") ? { error: input.error } : {}
9651
+ });
9652
+ }
9653
+ async function recordTurnDelivery(runDirectory, delivered, source) {
9654
+ try {
9655
+ reportRunRecord(runDirectory, "turn-delivery", {
9656
+ systemPrompt: delivered.systemPrompt,
9657
+ ...delivered.outputSchema === void 0 ? {} : { outputSchema: delivered.outputSchema }
9658
+ }, source);
9659
+ } catch (error) {
9660
+ await retainPackageFault({
9661
+ runDirectory,
9662
+ diagnostic: `turn delivery record failed beside host start: ${describeErrorIdentity(error)}`,
9663
+ error
9664
+ });
9665
+ }
9666
+ }
9667
+ function mergeRoleTurnAbortSignals(prepared, request) {
9668
+ if (request === void 0) return prepared;
9669
+ if (prepared === void 0) return request;
9670
+ return AbortSignal.any([prepared, request]);
9671
+ }
9672
+ function isHostAbortedError(error) {
9673
+ return typeof error === "object" && error !== null && error.code === "host-aborted";
9674
+ }
9675
+ function hostAbortedError(message = "host aborted") {
9676
+ return Object.assign(new Error(message), { code: "host-aborted" });
9677
+ }
9678
+ function raceAgainstHostAbort(work, abortSignal, message = "host aborted") {
9679
+ if (abortSignal?.aborted) return Promise.reject(hostAbortedError(message));
9680
+ if (abortSignal === void 0) return work;
9681
+ return new Promise((resolve21, reject) => {
9682
+ let settled = false;
9683
+ const onAbort = () => {
9684
+ if (settled) return;
9685
+ settled = true;
9686
+ work.catch(() => {
9687
+ });
9688
+ reject(hostAbortedError(message));
9689
+ };
9690
+ abortSignal.addEventListener("abort", onAbort, { once: true });
9691
+ work.then(
9692
+ (value) => {
9693
+ if (settled) return;
9694
+ settled = true;
9695
+ abortSignal.removeEventListener("abort", onAbort);
9696
+ resolve21(value);
9697
+ },
9698
+ (error) => {
9699
+ if (settled) return;
9700
+ settled = true;
9701
+ abortSignal.removeEventListener("abort", onAbort);
9702
+ reject(error);
9703
+ }
9704
+ );
9705
+ });
9706
+ }
9707
+ function externalHostFailure(cause, name, code, details, diagnostic) {
9708
+ return asFailure({
9709
+ cause,
9710
+ identity: { name, code },
9711
+ ...diagnostic === void 0 ? {} : { diagnostic },
9712
+ ...details === void 0 ? {} : { details }
9713
+ });
9714
+ }
9715
+ function asFailure(knownFailure, stderr = "") {
9716
+ return { code: null, stderr, timedOut: false, knownFailure };
9717
+ }
9718
+ async function settleHostAborted(prepared, sessionId) {
9719
+ const closure = await prepared.closeRound();
9720
+ if ("failure" in closure) return asFailure(closure.failure);
9721
+ return asFailure({
9722
+ cause: "session",
9723
+ identity: { name: "HostAborted", code: "host-aborted" },
9724
+ ...sessionId === void 0 ? {} : { details: { sessionId } }
9725
+ });
9726
+ }
9727
+ async function driveExternalRoleTurnRounds(prepared, request, driver) {
9728
+ let prompt = prepared.prompt;
9729
+ const abortSignal = mergeRoleTurnAbortSignals(prepared.abortSignal, request.signal);
9730
+ let result = { code: 0, stderr: "", timedOut: false };
9731
+ const countedReaskLimit = deliveryLimitFromConfig(request.deliveryRequestLimit);
9732
+ const exemptReminders = /* @__PURE__ */ new Set();
9733
+ let countedReasks = 0;
9734
+ for (let attempt = 0; ; attempt += 1) {
9735
+ if (abortSignal?.aborted) return settleHostAborted(prepared, driver.currentSessionId());
9736
+ let round;
9737
+ try {
9738
+ round = await driver.runRound({ prompt, abortSignal, attempt });
9739
+ } catch (error) {
9740
+ if (isHostAbortedError(error)) return settleHostAborted(prepared, driver.currentSessionId());
9741
+ throw error;
9742
+ }
9743
+ if (round.status === "terminal") return round.result;
9744
+ result = {
9745
+ code: round.code !== void 0 ? round.code : 0,
9746
+ stderr: round.stderr ?? "",
9747
+ timedOut: round.timedOut === true,
9748
+ ...round.signal === void 0 ? {} : { signal: round.signal }
9749
+ };
9750
+ let closure;
9751
+ try {
9752
+ closure = await prepared.closeRound();
9753
+ } catch (error) {
9754
+ await retainPackageFaultBesideLivePlacement(request, {
9755
+ diagnostic: `round closure failed beside host terminal: ${describeErrorIdentity(error)}`,
9756
+ error
9757
+ });
9758
+ return result.code === 0 && !result.timedOut && result.signal === void 0 ? { ...result, knownFailure: projectThrownFailureLeaf(error) } : result;
9759
+ }
9760
+ if (closure.accepted) {
9761
+ try {
9762
+ await driver.afterAccepted?.();
9763
+ } catch (error) {
9764
+ await retainPackageFaultBesideLivePlacement(request, {
9765
+ diagnostic: `post-acceptance close failed beside host terminal: ${describeErrorIdentity(error)}`,
9766
+ error
9767
+ });
9768
+ }
9769
+ return result;
9770
+ }
9771
+ if ("failure" in closure) {
9772
+ await retainPackageFaultBesideLivePlacement(request, {
9773
+ diagnostic: `round closure failed beside host terminal: ${JSON.stringify(closure.failure)}`
9774
+ });
9775
+ return result.code === 0 && !result.timedOut && result.signal === void 0 ? { ...result, knownFailure: closure.failure } : result;
9776
+ }
9777
+ if (result.code !== 0 || result.signal !== void 0 || result.timedOut) return result;
9778
+ const reminderCode = closure.retry.code;
9779
+ const exempt = isOneShotWorkerReminderCode(reminderCode) && !exemptReminders.has(reminderCode);
9780
+ if (exempt) exemptReminders.add(reminderCode);
9781
+ else {
9782
+ countedReasks += 1;
9783
+ if (countedReasks > countedReaskLimit) {
9784
+ await retainPackageFaultBesideLivePlacement(request, {
9785
+ diagnostic: `${driver.roundLimitName}: round-retry-limit`
9786
+ });
9787
+ return result;
9788
+ }
9789
+ }
9790
+ prompt = closure.retry.message;
9791
+ driver.afterRetry?.();
9792
+ }
9793
+ }
9794
+ async function disposeExternalRoleTurn(prepared, request, outcome) {
9795
+ try {
9796
+ await prepared.dispose?.();
9797
+ } catch (error) {
9798
+ await retainPackageFaultBesideLivePlacement(request, {
9799
+ diagnostic: `required envelope shutdown failed beside host terminal: ${describeErrorIdentity(error)}`,
9800
+ error
9801
+ });
9802
+ if (outcome.code === 0 && !outcome.timedOut && outcome.signal === void 0 && outcome.knownFailure === void 0) {
9803
+ return { ...outcome, knownFailure: projectThrownFailureLeaf(error) };
9804
+ }
9805
+ }
9806
+ return outcome;
9807
+ }
9808
+ function createSerializedRoleTurnHost(execute) {
9809
+ let serial = Promise.resolve();
9810
+ return {
9811
+ executeTurn(request) {
9812
+ const execution = serial.then(() => execute(request));
9813
+ serial = execution.then(() => void 0, () => void 0);
9814
+ return execution;
9815
+ }
9816
+ };
9817
+ }
9818
+ var init_external_host_turn_loop = __esm({
9819
+ "src/external-host-turn-loop.ts"() {
9820
+ "use strict";
9821
+ init_activation_ledger_topology();
9822
+ init_settlement();
9823
+ init_run_lifecycle();
9824
+ init_receipt_delivery_policy();
9825
+ init_role_run_placement();
9826
+ init_role_run_relocation();
9827
+ init_sitian_facade();
9828
+ init_submission_errors();
9829
+ }
9830
+ });
9831
+
9580
9832
  // src/session-identity.ts
9581
9833
  import { dirname as dirname9, join as join11 } from "node:path";
9582
9834
  function createSessionIdentityAuthority(authority, hostName) {
@@ -9656,6 +9908,7 @@ __export(role_turn_host_exports, {
9656
9908
  });
9657
9909
  import { execFile as execFile2, spawn as spawn2 } from "node:child_process";
9658
9910
  import { constants } from "node:fs";
9911
+ import { existsSync as existsSync5 } from "node:fs";
9659
9912
  import { access as access2, appendFile, realpath as realpath4 } from "node:fs/promises";
9660
9913
  import { delimiter, dirname as dirname10, isAbsolute as isAbsolute6, join as join12, resolve as resolve11 } from "node:path";
9661
9914
  import { platform } from "node:process";
@@ -9841,7 +10094,32 @@ function createDefaultPiSpawnRunner(options) {
9841
10094
  if (stdinDeliveryError !== void 0) packageErrors.push(stdinDeliveryError);
9842
10095
  for (const error of packageErrors) {
9843
10096
  const diagnostic = `Pi transport handling failed beside host terminal: ${describeErrorIdentity(error)}`;
9844
- const runDirectory = spawnOptions.env.AK_ROLE_RUN_DIR;
10097
+ const spawnDir = spawnOptions.env.AK_ROLE_RUN_DIR;
10098
+ let runDirectory;
10099
+ if (typeof spawnDir === "string" && spawnDir.trim() !== "") {
10100
+ try {
10101
+ runDirectory = await resolveLiveRunDirectoryPath(
10102
+ spawnDir,
10103
+ homeFromRunDirectory(spawnDir)
10104
+ );
10105
+ } catch (resolveError) {
10106
+ runDirectory = existsSync5(spawnDir) ? spawnDir : void 0;
10107
+ const resolveDiagnostic = `live run path resolve failed beside Pi transport fault: ${describeErrorIdentity(resolveError)}`;
10108
+ if (runDirectory !== void 0) {
10109
+ await retainPackageFault({
10110
+ runDirectory,
10111
+ diagnostic: resolveDiagnostic,
10112
+ error: resolveError
10113
+ });
10114
+ } else {
10115
+ try {
10116
+ process.stderr.write(`${resolveDiagnostic}
10117
+ `);
10118
+ } catch {
10119
+ }
10120
+ }
10121
+ }
10122
+ }
9845
10123
  if (runDirectory !== void 0) {
9846
10124
  await retainPackageFault({ runDirectory, diagnostic, error });
9847
10125
  } else {
@@ -9923,6 +10201,7 @@ function createPiRoleTurnHost(config) {
9923
10201
  ...request.signal === void 0 ? {} : { signal: request.signal }
9924
10202
  });
9925
10203
  try {
10204
+ await syncTurnRequestLivePlacement(request);
9926
10205
  const { sessionFile, sessionDirectory } = config.principalAuthority.decode(request.principal);
9927
10206
  const sessionId = await readPiSessionHeaderId(sessionFile);
9928
10207
  if (sessionId !== void 0) {
@@ -9940,8 +10219,7 @@ function createPiRoleTurnHost(config) {
9940
10219
  });
9941
10220
  }
9942
10221
  } catch (error) {
9943
- await retainPackageFault({
9944
- runDirectory: request.runDirectory,
10222
+ await retainPackageFaultBesideLivePlacement(request, {
9945
10223
  diagnostic: `pi host dossier record failed beside host terminal: ${describeErrorIdentity(error)}`,
9946
10224
  error
9947
10225
  });
@@ -10010,6 +10288,8 @@ var init_role_turn_host = __esm({
10010
10288
  init_user_dialogue_stdin();
10011
10289
  init_ledger_session_read();
10012
10290
  init_host_session_record();
10291
+ init_external_host_turn_loop();
10292
+ init_activation_ledger_topology();
10013
10293
  init_settlement();
10014
10294
  init_run_lifecycle();
10015
10295
  init_receipt_delivery_policy();
@@ -10029,7 +10309,7 @@ var init_role_turn_host = __esm({
10029
10309
  });
10030
10310
 
10031
10311
  // src/package-resources/engine-material.ts
10032
- import { existsSync as existsSync4, readdirSync as readdirSync2, readFileSync as readFileSync2 } from "node:fs";
10312
+ import { existsSync as existsSync6, readdirSync as readdirSync2, readFileSync as readFileSync2 } from "node:fs";
10033
10313
  import { join as join13 } from "node:path";
10034
10314
  function pickEngineAxis(source) {
10035
10315
  return {
@@ -10075,12 +10355,12 @@ function engineSessionMaterialFromOptions(options) {
10075
10355
  const model = options.engineModel === void 0 ? void 0 : assertLegalEngineModel(options.engineModel);
10076
10356
  const materialPath = resolveEngineMaterialPath(options.packageRoot, name);
10077
10357
  const modelField = model === void 0 ? {} : { model };
10078
- if (!existsSync4(materialPath)) {
10358
+ if (!existsSync6(materialPath)) {
10079
10359
  return Object.freeze({ name, ...modelField });
10080
10360
  }
10081
10361
  const handbook = readFileSync2(materialPath, "utf8");
10082
10362
  const dispatchPath = resolveEngineDispatchMaterialPath(options.packageRoot);
10083
- const dispatchField = existsSync4(dispatchPath) ? { dispatchHandbook: readFileSync2(dispatchPath, "utf8") } : {};
10363
+ const dispatchField = existsSync6(dispatchPath) ? { dispatchHandbook: readFileSync2(dispatchPath, "utf8") } : {};
10084
10364
  return Object.freeze({ name, handbook, ...dispatchField, ...modelField });
10085
10365
  }
10086
10366
  function engineSessionReadingMaterial(engineMaterial) {
@@ -10812,7 +11092,7 @@ var init_host_providers = __esm({
10812
11092
  });
10813
11093
 
10814
11094
  // src/public-cli/load-production-acp-host.ts
10815
- import { existsSync as existsSync5 } from "node:fs";
11095
+ import { existsSync as existsSync7 } from "node:fs";
10816
11096
  import { join as join16 } from "node:path";
10817
11097
  import { pathToFileURL } from "node:url";
10818
11098
  async function loadProductionAcpHostFactory(packageRoot, host) {
@@ -10822,7 +11102,7 @@ async function loadProductionAcpHostFactory(packageRoot, host) {
10822
11102
  }
10823
11103
  const built = join16(packageRoot, "dist/acp-host/production-host.js");
10824
11104
  const source = join16(packageRoot, "src/acp-host/production-host.ts");
10825
- const target = existsSync5(built) ? built : source;
11105
+ const target = existsSync7(built) ? built : source;
10826
11106
  const href = pathToFileURL(target).href;
10827
11107
  const mod = await import(href);
10828
11108
  const create = mod.createProductionAcpRoleTurnHost;
@@ -10836,7 +11116,7 @@ var init_load_production_acp_host = __esm({
10836
11116
  });
10837
11117
 
10838
11118
  // src/public-cli/load-production-headless-host.ts
10839
- import { existsSync as existsSync6 } from "node:fs";
11119
+ import { existsSync as existsSync8 } from "node:fs";
10840
11120
  import { join as join17 } from "node:path";
10841
11121
  import { pathToFileURL as pathToFileURL2 } from "node:url";
10842
11122
  async function loadProductionHeadlessHostFactory(packageRoot, host) {
@@ -10846,7 +11126,7 @@ async function loadProductionHeadlessHostFactory(packageRoot, host) {
10846
11126
  }
10847
11127
  const built = join17(packageRoot, "dist/headless-host/production-host.js");
10848
11128
  const source = join17(packageRoot, "src/headless-host/production-host.ts");
10849
- const target = existsSync6(built) ? built : source;
11129
+ const target = existsSync8(built) ? built : source;
10850
11130
  const href = pathToFileURL2(target).href;
10851
11131
  const mod = await import(href);
10852
11132
  const create = mod.createProductionHeadlessRoleTurnHost;
@@ -11012,8 +11292,179 @@ var init_role_seat_runtime = __esm({
11012
11292
  }
11013
11293
  });
11014
11294
 
11295
+ // src/report-ticket-tool.ts
11296
+ import { Type as Type15 } from "typebox";
11297
+ import { existsSync as existsSync9 } from "node:fs";
11298
+ function pageString(page, key) {
11299
+ const value = page?.[key];
11300
+ return typeof value === "string" && value.trim() !== "" ? value : void 0;
11301
+ }
11302
+ function admittedForLiveTicketReport(runDirectory, authority) {
11303
+ const admittedPage = readPageSync(runDirectory, "admitted") ?? {};
11304
+ const invocationPage = readPageSync(runDirectory, "invocation") ?? {};
11305
+ const role = pageString(admittedPage, "role") ?? pageString(invocationPage, "role");
11306
+ const runId = pageString(admittedPage, "runId") ?? pageString(invocationPage, "runId");
11307
+ const bookKey = pageString(admittedPage, "bookKey") ?? pageString(invocationPage, "bookKey");
11308
+ const projectRoot = pageString(admittedPage, "projectRoot") ?? pageString(invocationPage, "projectRoot");
11309
+ if (role === void 0 || runId === void 0 || bookKey === void 0 || projectRoot === void 0) {
11310
+ throw new Error("ak_report_ticket requires durable role/runId/bookKey/projectRoot on the run");
11311
+ }
11312
+ const attachments = Array.isArray(admittedPage.attachments) ? admittedPage.attachments : [];
11313
+ const sessionDirectory = sessionDirectoryOf(runDirectory);
11314
+ const sessionFile = sessionFileOf(runDirectory);
11315
+ const principal = authority.seal({ sessionDirectory, sessionFile });
11316
+ const ticketNumber = readDeclaredTicketNumber(admittedPage.ticketNumber) ?? readDeclaredTicketNumber(invocationPage.ticketNumber);
11317
+ return {
11318
+ role,
11319
+ runId,
11320
+ bookKey,
11321
+ projectRoot,
11322
+ instruction: typeof admittedPage.instruction === "string" ? admittedPage.instruction : "",
11323
+ instructionEmpty: admittedPage.instructionEmpty === true || typeof admittedPage.instruction === "string" && admittedPage.instruction.trim() === "",
11324
+ attachments,
11325
+ runDirectory,
11326
+ principal,
11327
+ ...ticketNumber === void 0 ? {} : { ticketNumber }
11328
+ };
11329
+ }
11330
+ async function reportTicketFromHostContext(context, rawTicketNumber, authority = piDurablePrincipalAuthority) {
11331
+ const ticketNumber = readDeclaredTicketNumber(rawTicketNumber);
11332
+ if (ticketNumber === void 0) {
11333
+ throw new Error("ak_report_ticket requires an identifiable ticketNumber");
11334
+ }
11335
+ const runDirectory = runDirectoryFromHostContext(context);
11336
+ if (runDirectory === void 0) {
11337
+ throw new Error("ak_report_ticket requires a per-turn run directory");
11338
+ }
11339
+ if (!existsSync9(runDirectory)) {
11340
+ throw new Error(`ak_report_ticket run directory missing: ${runDirectory}`);
11341
+ }
11342
+ const admitted = admittedForLiveTicketReport(runDirectory, authority);
11343
+ const alreadyPlaced = !isUnboundRunDirectory(runDirectory);
11344
+ if (!alreadyPlaced) {
11345
+ await bindAdmittedTicketNumber(admitted, ticketNumber);
11346
+ }
11347
+ const applyLiveHandles = (nextDirectory2) => {
11348
+ context.runDirectory = nextDirectory2;
11349
+ if (process.env.AK_ROLE_RUN_DIR === runDirectory) {
11350
+ process.env.AK_ROLE_RUN_DIR = nextDirectory2;
11351
+ }
11352
+ context.sessionManager.setSessionFile?.(sessionFileOf(nextDirectory2));
11353
+ };
11354
+ const relocation = alreadyPlaced ? void 0 : await relocateAdmittedRunToTicket(admitted, authority, { relocate: applyLiveHandles });
11355
+ const nextDirectory = relocation?.newRunDirectory ?? admitted.runDirectory;
11356
+ if (relocation === void 0) applyLiveHandles(nextDirectory);
11357
+ return {
11358
+ ticketNumber: alreadyPlaced ? admitted.ticketNumber ?? ticketNumber : ticketNumber,
11359
+ relocated: relocation !== void 0
11360
+ };
11361
+ }
11362
+ function registerReportTicketTool(roleHost) {
11363
+ if (roleHost.getAllTools().some((tool) => tool.name === REPORT_TICKET_TOOL_NAME)) return;
11364
+ roleHost.registerTool({
11365
+ name: REPORT_TICKET_TOOL_NAME,
11366
+ label: "\u62A5\u7968\u53F7",
11367
+ description: REPORT_TICKET_TOOL_DESCRIPTION,
11368
+ promptSnippet: "\u5DF2\u77E5\u7968\u53F7\u65F6\u7ACB\u5373\u7533\u62A5\uFF0C\u5305\u5F53\u573A\u5F52\u4F4D",
11369
+ parameters: reportTicketArgsSchema,
11370
+ async execute(_toolCallId, parameters, _signal, _onUpdate, ctx) {
11371
+ const raw = isRecord(parameters) ? parameters.ticketNumber : void 0;
11372
+ const details = await reportTicketFromHostContext(ctx, raw);
11373
+ return {
11374
+ content: [],
11375
+ details
11376
+ };
11377
+ }
11378
+ });
11379
+ }
11380
+ var REPORT_TICKET_TOOL_NAME, reportTicketArgsSchema, REPORT_TICKET_TOOL_DESCRIPTION, MISSING_TICKET_REASK_MATERIAL;
11381
+ var init_report_ticket_tool = __esm({
11382
+ "src/report-ticket-tool.ts"() {
11383
+ "use strict";
11384
+ init_host_contracts();
11385
+ init_durable_principal();
11386
+ init_invocation();
11387
+ init_role_run_placement();
11388
+ init_run_dossier();
11389
+ init_run_ticket_number();
11390
+ init_unknown_value();
11391
+ REPORT_TICKET_TOOL_NAME = "ak_report_ticket";
11392
+ reportTicketArgsSchema = Type15.Object(
11393
+ {
11394
+ ticketNumber: Type15.Unknown({
11395
+ 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"
11396
+ })
11397
+ },
11398
+ { additionalProperties: true }
11399
+ );
11400
+ 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";
11401
+ MISSING_TICKET_REASK_MATERIAL = "resources/missing-ticket-reask.md";
11402
+ }
11403
+ });
11404
+
11405
+ // src/session-opening-materials.ts
11406
+ import { existsSync as existsSync10 } from "node:fs";
11407
+ import { readFile as readFile9 } from "node:fs/promises";
11408
+ import { dirname as dirname12, join as join18 } from "node:path";
11409
+ import { fileURLToPath, pathToFileURL as pathToFileURL3 } from "node:url";
11410
+ function resolvePackageRootDir(moduleUrl = import.meta.url) {
11411
+ let dir = dirname12(fileURLToPath(moduleUrl));
11412
+ for (let i = 0; i < 8; i += 1) {
11413
+ if (existsSync10(join18(dir, "package.json")) && existsSync10(join18(dir, "souls"))) {
11414
+ return dir;
11415
+ }
11416
+ const parent = dirname12(dir);
11417
+ if (parent === dir) break;
11418
+ dir = parent;
11419
+ }
11420
+ return fileURLToPath(new URL("..", moduleUrl));
11421
+ }
11422
+ async function readPackageMaterial(relativePath) {
11423
+ return readFile9(fileURLToPath(new URL(relativePath, packageRootUrl)), "utf8");
11424
+ }
11425
+ async function joinPackageMaterials(relativePaths) {
11426
+ const chunks = [];
11427
+ for (const relativePath of relativePaths) chunks.push(await readPackageMaterial(relativePath));
11428
+ return chunks.join("\n\n");
11429
+ }
11430
+ function roleSoulPath(role, materials) {
11431
+ const suffix = `/souls/${role}.md`;
11432
+ const path = materials.find((candidate) => `/${candidate}`.endsWith(suffix));
11433
+ if (path === void 0) throw new Error(`session materials omit the ${role} Soul`);
11434
+ return path;
11435
+ }
11436
+ async function loadSeparatedSessionPart(role, materials, part) {
11437
+ const soul = roleSoulPath(role, materials);
11438
+ return part === "soul" ? readPackageMaterial(soul) : joinPackageMaterials(materials.filter((path) => path !== soul));
11439
+ }
11440
+ function loadMainRoleSessionMaterials(role) {
11441
+ return loadSeparatedSessionPart(role, MAIN_ROLE_SESSION_MATERIALS[role], "soul");
11442
+ }
11443
+ function loadMainRoleReferenceMaterials(role) {
11444
+ return loadSeparatedSessionPart(role, MAIN_ROLE_SESSION_MATERIALS[role], "references");
11445
+ }
11446
+ var packageRootUrl, MAIN_ROLE_SESSION_MATERIALS, GATEKEEPER_SESSION_MATERIALS;
11447
+ var init_session_opening_materials = __esm({
11448
+ "src/session-opening-materials.ts"() {
11449
+ "use strict";
11450
+ init_packaged_role_registry();
11451
+ packageRootUrl = pathToFileURL3(resolvePackageRootDir() + "/").href;
11452
+ MAIN_ROLE_SESSION_MATERIALS = {
11453
+ ...Object.fromEntries(
11454
+ PUBLIC_ROLE_RECORDS.map((record) => [record.role, record.sessionMaterials])
11455
+ )
11456
+ };
11457
+ GATEKEEPER_SESSION_MATERIALS = {
11458
+ // #639: single authority — the public gatekeeper record owns the province list.
11459
+ gatekeeper: packagedRoleSessionMaterials("gatekeeper"),
11460
+ inspector: INSPECTOR_SESSION_MATERIALS,
11461
+ notary: NOTARY_SESSION_MATERIALS
11462
+ };
11463
+ }
11464
+ });
11465
+
11015
11466
  // src/archivist-record-pointer.ts
11016
- import { basename as basename8, join as join18 } from "node:path";
11467
+ import { basename as basename9, join as join19 } from "node:path";
11017
11468
  function bookDirectOfficerRunPointer(options) {
11018
11469
  const submissionToolCallId = options.submissionToolCallId?.trim() ?? "";
11019
11470
  const pointer = {
@@ -11039,7 +11490,7 @@ async function resolveOfficerPointer(raw, parentRunDirectory) {
11039
11490
  let runDirectory = typeof raw.runDirectory === "string" && raw.runDirectory.trim() !== "" ? raw.runDirectory : void 0;
11040
11491
  let sessionFile = raw.sessionFile;
11041
11492
  const recordedRunDirectory = runDirectory ?? runDirectoryOfSessionFile(sessionFile);
11042
- const leaf = parseRunLeaf(basename8(recordedRunDirectory));
11493
+ const leaf = parseRunLeaf(basename9(recordedRunDirectory));
11043
11494
  const parentIdentity = await readRoleRunIdentity(parentRunDirectory);
11044
11495
  if (leaf !== void 0 && parentIdentity !== void 0) {
11045
11496
  const currentRunDirectory = await findRunDirectoryById(
@@ -11062,7 +11513,7 @@ async function resolveOfficerPointer(raw, parentRunDirectory) {
11062
11513
  };
11063
11514
  }
11064
11515
  async function readBookedOfficerPointers(parentRunDirectory) {
11065
- const { records, diagnostics } = await readSitianRecords(join18(parentRunDirectory, RUN_HISTORY_FILE));
11516
+ const { records, diagnostics } = await readSitianRecords(join19(parentRunDirectory, RUN_HISTORY_FILE));
11066
11517
  if (diagnostics.length > 0) {
11067
11518
  throw new Error(
11068
11519
  `${RUN_HISTORY_FILE} has ${diagnostics.length} malformed row(s); officer pointers unreadable: ${parentRunDirectory}`
@@ -11398,67 +11849,6 @@ var init_submission_gate = __esm({
11398
11849
  }
11399
11850
  });
11400
11851
 
11401
- // src/session-opening-materials.ts
11402
- import { existsSync as existsSync7 } from "node:fs";
11403
- import { readFile as readFile9 } from "node:fs/promises";
11404
- import { dirname as dirname12, join as join19 } from "node:path";
11405
- import { fileURLToPath, pathToFileURL as pathToFileURL3 } from "node:url";
11406
- function resolvePackageRootDir(moduleUrl = import.meta.url) {
11407
- let dir = dirname12(fileURLToPath(moduleUrl));
11408
- for (let i = 0; i < 8; i += 1) {
11409
- if (existsSync7(join19(dir, "package.json")) && existsSync7(join19(dir, "souls"))) {
11410
- return dir;
11411
- }
11412
- const parent = dirname12(dir);
11413
- if (parent === dir) break;
11414
- dir = parent;
11415
- }
11416
- return fileURLToPath(new URL("..", moduleUrl));
11417
- }
11418
- async function readPackageMaterial(relativePath) {
11419
- return readFile9(fileURLToPath(new URL(relativePath, packageRootUrl)), "utf8");
11420
- }
11421
- async function joinPackageMaterials(relativePaths) {
11422
- const chunks = [];
11423
- for (const relativePath of relativePaths) chunks.push(await readPackageMaterial(relativePath));
11424
- return chunks.join("\n\n");
11425
- }
11426
- function roleSoulPath(role, materials) {
11427
- const suffix = `/souls/${role}.md`;
11428
- const path = materials.find((candidate) => `/${candidate}`.endsWith(suffix));
11429
- if (path === void 0) throw new Error(`session materials omit the ${role} Soul`);
11430
- return path;
11431
- }
11432
- async function loadSeparatedSessionPart(role, materials, part) {
11433
- const soul = roleSoulPath(role, materials);
11434
- return part === "soul" ? readPackageMaterial(soul) : joinPackageMaterials(materials.filter((path) => path !== soul));
11435
- }
11436
- function loadMainRoleSessionMaterials(role) {
11437
- return loadSeparatedSessionPart(role, MAIN_ROLE_SESSION_MATERIALS[role], "soul");
11438
- }
11439
- function loadMainRoleReferenceMaterials(role) {
11440
- return loadSeparatedSessionPart(role, MAIN_ROLE_SESSION_MATERIALS[role], "references");
11441
- }
11442
- var packageRootUrl, MAIN_ROLE_SESSION_MATERIALS, GATEKEEPER_SESSION_MATERIALS;
11443
- var init_session_opening_materials = __esm({
11444
- "src/session-opening-materials.ts"() {
11445
- "use strict";
11446
- init_packaged_role_registry();
11447
- packageRootUrl = pathToFileURL3(resolvePackageRootDir() + "/").href;
11448
- MAIN_ROLE_SESSION_MATERIALS = {
11449
- ...Object.fromEntries(
11450
- PUBLIC_ROLE_RECORDS.map((record) => [record.role, record.sessionMaterials])
11451
- )
11452
- };
11453
- GATEKEEPER_SESSION_MATERIALS = {
11454
- // #639: single authority — the public gatekeeper record owns the province list.
11455
- gatekeeper: packagedRoleSessionMaterials("gatekeeper"),
11456
- inspector: INSPECTOR_SESSION_MATERIALS,
11457
- notary: NOTARY_SESSION_MATERIALS
11458
- };
11459
- }
11460
- });
11461
-
11462
11852
  // src/auditor-soul.ts
11463
11853
  var auditor_soul_exports = {};
11464
11854
  __export(auditor_soul_exports, {
@@ -11474,7 +11864,7 @@ __export(auditor_soul_exports, {
11474
11864
  readAuditorResumeBinding: () => readAuditorResumeBinding,
11475
11865
  resolveAuditorSubject: () => resolveAuditorSubject
11476
11866
  });
11477
- import { basename as basename9 } from "node:path";
11867
+ import { basename as basename10 } from "node:path";
11478
11868
  function auditorSoulRelativePath(role) {
11479
11869
  return `souls/${role}-auditor.md`;
11480
11870
  }
@@ -11510,7 +11900,7 @@ function loadAuditorReferenceMaterialsFromSubjectInput(raw) {
11510
11900
  return loadAuditorReferenceMaterials(resolveAuditorSubject(raw));
11511
11901
  }
11512
11902
  function subjectFromSourceDirectory(sourceRunDirectory) {
11513
- const role = parseRunLeaf(basename9(sourceRunDirectory))?.role;
11903
+ const role = parseRunLeaf(basename10(sourceRunDirectory))?.role;
11514
11904
  return isAuditorSoulRole(role) ? role : void 0;
11515
11905
  }
11516
11906
  async function readAuditorResumeBinding(runDirectory) {
@@ -12072,6 +12462,7 @@ var init_auto_resume = __esm({
12072
12462
 
12073
12463
  // src/public-cli/post-admission.ts
12074
12464
  import { randomUUID as randomUUID5 } from "node:crypto";
12465
+ import { existsSync as existsSync11 } from "node:fs";
12075
12466
  function describeCaughtError(error) {
12076
12467
  if (error instanceof Error) {
12077
12468
  const code = error.code;
@@ -12104,6 +12495,91 @@ function projectRelocatedTurnIdentity(request, result, admitted, relocation) {
12104
12495
  }
12105
12496
  }
12106
12497
  }
12498
+ async function refreshAdmittedPlacementAfterHostTurn(admitted, authority, heldLease) {
12499
+ const home = homeFromRunDirectory(admitted.runDirectory);
12500
+ const found = await findRunDirectoryById(home, admitted.runId, admitted.bookKey, admitted.role);
12501
+ if (found === void 0 && !existsSync11(admitted.runDirectory)) {
12502
+ throw new Error(
12503
+ `admitted run ${admitted.runId} missing after host turn; not found under ${home}`
12504
+ );
12505
+ }
12506
+ let relocation;
12507
+ if (found !== void 0 && found !== admitted.runDirectory) {
12508
+ const oldRunDirectory = admitted.runDirectory;
12509
+ const coords = { ...authority.decode(admitted.principal) };
12510
+ rewritePrincipalSessionPaths(
12511
+ coords,
12512
+ oldRunDirectory,
12513
+ found
12514
+ );
12515
+ const principal = authority.seal(coords);
12516
+ rewriteAdmittedRoleRunPage(
12517
+ admitted,
12518
+ [{ oldRunDirectory, newRunDirectory: found }]
12519
+ );
12520
+ admitted.principal = principal;
12521
+ heldLease?.relocate(found);
12522
+ relocation = { oldRunDirectory, newRunDirectory: found };
12523
+ }
12524
+ if (admitted.ticketNumber === void 0) {
12525
+ const boardTicket = await readBoardTicketNumber(found ?? admitted.runDirectory);
12526
+ if (boardTicket !== void 0) {
12527
+ admitted.ticketNumber = boardTicket;
12528
+ }
12529
+ }
12530
+ return relocation;
12531
+ }
12532
+ function applyRefreshedPlacementToTurn(request, turnRequest, admitted, refreshed) {
12533
+ projectRelocatedTurnIdentity(request, {}, admitted, refreshed);
12534
+ return {
12535
+ ...turnRequest,
12536
+ runDirectory: admitted.runDirectory,
12537
+ principal: admitted.principal
12538
+ };
12539
+ }
12540
+ async function settleHostThrowAfterLivePlacementRefresh(input) {
12541
+ let refreshError;
12542
+ let turnRequest = input.turnRequest;
12543
+ try {
12544
+ const refreshed = await refreshAdmittedPlacementAfterHostTurn(
12545
+ input.admitted,
12546
+ input.env.principalAuthority,
12547
+ input.lease
12548
+ );
12549
+ if (refreshed !== void 0) {
12550
+ turnRequest = applyRefreshedPlacementToTurn(
12551
+ input.request,
12552
+ turnRequest,
12553
+ input.admitted,
12554
+ refreshed
12555
+ );
12556
+ }
12557
+ } catch (err) {
12558
+ refreshError = err;
12559
+ }
12560
+ const processCancelName = processCancelSignalName(input.env.signal);
12561
+ const hostThrowSecondary = refreshError !== void 0 && input.hostTurnCompleted === false ? { knownDetails: { hostThrow: describeCaughtError(input.hostError) } } : {};
12562
+ const settled = await settleAfterTurnStarted(
12563
+ input.admitted,
12564
+ withEngineDetourInvocationScope({
12565
+ timedOut: false,
12566
+ code: null,
12567
+ stderr: "",
12568
+ // Prefer the refresh failure when the live path is gone; otherwise the
12569
+ // host throw remains the cause (失败诚实:不在旧 unbound 上结算写回).
12570
+ ...processCancelName === void 0 ? {} : { cancelName: processCancelName },
12571
+ thrown: refreshError ?? input.hostError,
12572
+ ...hostThrowSecondary
12573
+ }, input.request.invocationScopeId),
12574
+ input.adapters,
12575
+ input.env.principalAuthority,
12576
+ input.io,
12577
+ input.persistRunState,
12578
+ input.notePackageFault,
12579
+ input.courtAttemptId
12580
+ );
12581
+ return { settled, turnRequest };
12582
+ }
12107
12583
  function withProcessCancelSkipAutoResume(result, signal) {
12108
12584
  if (processCancelSignalName(signal) === void 0) {
12109
12585
  return result;
@@ -12490,6 +12966,12 @@ async function dispatchPostAdmissionTurn(input) {
12490
12966
  }
12491
12967
  if (pendingSettlement !== void 0 && pendingTerminal !== void 0 && result.terminal === pendingTerminal) {
12492
12968
  try {
12969
+ const softTicketReaskNoSeal = pendingSettlement !== "sealed" && env.softTicketReaskTurn === true;
12970
+ const noSealScope = softTicketReaskNoSeal ? {
12971
+ ...courtScope,
12972
+ previewOnly: true,
12973
+ recordAttemptHistory: true
12974
+ } : { ...courtScope, recordAttemptHistory: true };
12493
12975
  const terminal = pendingSettlement === "sealed" ? await adapters.trySettle(
12494
12976
  admitted,
12495
12977
  env.principalAuthority,
@@ -12499,13 +12981,16 @@ async function dispatchPostAdmissionTurn(input) {
12499
12981
  await settleHostEndedNoReceipt(
12500
12982
  admitted,
12501
12983
  env.principalAuthority,
12502
- { ...courtScope, recordAttemptHistory: true },
12984
+ noSealScope,
12503
12985
  receiptDelivery.issuedDeliveryRequests()
12504
12986
  ),
12505
- courtScope
12987
+ noSealScope
12506
12988
  );
12507
12989
  if (terminal === void 0) throw new Error("settled host attempt vanished before publication");
12508
12990
  result = { ...result, terminal, exitCode: exitCodeForTerminalOutcome(terminal.roleOutcome) };
12991
+ if (pendingSettlement === "sealed" && env.softTicketReaskTurn === true && env.softTicketReaskOwnership !== void 0) {
12992
+ env.softTicketReaskOwnership.sealedSubstitute = true;
12993
+ }
12509
12994
  if (pendingSettlement === "sealed" && terminal.roleOutcome.kind === "accepted" && request.courtAttemptId !== void 0 && request.courtAttemptId.length > 0) {
12510
12995
  try {
12511
12996
  await clearCurrentCourt(admitted.runDirectory, request.courtAttemptId);
@@ -12615,32 +13100,38 @@ async function dispatchPostAdmissionTurn(input) {
12615
13100
  env.engineModel
12616
13101
  );
12617
13102
  let result;
13103
+ let hostTurnCompleted = false;
12618
13104
  try {
12619
13105
  turnDispatched = true;
12620
13106
  result = await env.roleTurnHost.executeTurn(turnRequest);
13107
+ hostTurnCompleted = true;
13108
+ const refreshed = await refreshAdmittedPlacementAfterHostTurn(
13109
+ admitted,
13110
+ env.principalAuthority,
13111
+ lease
13112
+ );
13113
+ if (refreshed !== void 0) {
13114
+ turnRequest = applyRefreshedPlacementToTurn(request, turnRequest, admitted, refreshed);
13115
+ }
12621
13116
  } catch (error) {
12622
- const processCancelName = processCancelSignalName(env.signal);
12623
- const settled = await settleAfterTurnStarted(
13117
+ const thrown = await settleHostThrowAfterLivePlacementRefresh({
12624
13118
  admitted,
12625
- withEngineDetourInvocationScope({
12626
- timedOut: false,
12627
- code: null,
12628
- stderr: "",
12629
- // The thrown value is the host's report. A cancel received on this
12630
- // call is a second fact; it must not become a new Error in its place.
12631
- ...processCancelName === void 0 ? {} : { cancelName: processCancelName },
12632
- thrown: error
12633
- }, request.invocationScopeId),
13119
+ hostError: error,
13120
+ hostTurnCompleted,
13121
+ request,
13122
+ turnRequest,
13123
+ lease,
12634
13124
  adapters,
12635
- env.principalAuthority,
13125
+ env,
12636
13126
  io,
12637
13127
  persistRunState,
12638
- courtScope.notePackageFault,
12639
- courtScope.courtAttemptId
12640
- );
13128
+ notePackageFault: courtScope.notePackageFault,
13129
+ ...courtScope.courtAttemptId === void 0 ? {} : { courtAttemptId: courtScope.courtAttemptId }
13130
+ });
13131
+ turnRequest = thrown.turnRequest;
12641
13132
  return await finishAfterTurn(
12642
13133
  withProcessCancelSkipAutoResume(
12643
- { ...settled, turnDispatched: true, ...deferredPersist },
13134
+ { ...thrown.settled, turnDispatched: true, ...deferredPersist },
12644
13135
  env.signal
12645
13136
  )
12646
13137
  );
@@ -12666,6 +13157,7 @@ async function dispatchPostAdmissionTurn(input) {
12666
13157
  while (akSeamDeliversReceipt && receiptDelivery.nextAction() === "request-delivery") {
12667
13158
  let deliveryResult;
12668
13159
  let deliveryTurnRequest;
13160
+ let deliveryHostTurnCompleted = false;
12669
13161
  try {
12670
13162
  const deliveryRequest = buildReceiptDeliveryRequest({
12671
13163
  request: turnRequest,
@@ -12679,24 +13171,40 @@ async function dispatchPostAdmissionTurn(input) {
12679
13171
  };
12680
13172
  receiptDelivery.recordDeliveryRequest();
12681
13173
  deliveryResult = await env.roleTurnHost.executeTurn(deliveryTurnRequest);
13174
+ deliveryHostTurnCompleted = true;
13175
+ const refreshed = await refreshAdmittedPlacementAfterHostTurn(
13176
+ admitted,
13177
+ env.principalAuthority,
13178
+ lease
13179
+ );
13180
+ if (refreshed !== void 0) {
13181
+ turnRequest = applyRefreshedPlacementToTurn(request, turnRequest, admitted, refreshed);
13182
+ deliveryTurnRequest = {
13183
+ ...deliveryTurnRequest,
13184
+ runDirectory: admitted.runDirectory,
13185
+ principal: admitted.principal
13186
+ };
13187
+ }
12682
13188
  } catch (error) {
12683
- const settled = await settleAfterTurnStarted(
13189
+ const thrown = await settleHostThrowAfterLivePlacementRefresh({
12684
13190
  admitted,
12685
- withEngineDetourInvocationScope(
12686
- { timedOut: false, code: null, stderr: "", thrown: error },
12687
- request.invocationScopeId
12688
- ),
13191
+ hostError: error,
13192
+ hostTurnCompleted: deliveryHostTurnCompleted,
13193
+ request,
13194
+ turnRequest,
13195
+ lease,
12689
13196
  adapters,
12690
- env.principalAuthority,
13197
+ env,
12691
13198
  io,
12692
13199
  persistRunState,
12693
- courtScope.notePackageFault,
12694
- courtScope.courtAttemptId
12695
- );
13200
+ notePackageFault: courtScope.notePackageFault,
13201
+ ...courtScope.courtAttemptId === void 0 ? {} : { courtAttemptId: courtScope.courtAttemptId }
13202
+ });
13203
+ turnRequest = thrown.turnRequest;
12696
13204
  return await finishAfterTurn(
12697
13205
  withProcessCancelSkipAutoResume(
12698
13206
  {
12699
- ...settled,
13207
+ ...thrown.settled,
12700
13208
  turnDispatched: true,
12701
13209
  ...deferredPersist
12702
13210
  },
@@ -13212,6 +13720,7 @@ var init_post_admission = __esm({
13212
13720
  init_invocation();
13213
13721
  init_submission_ledger();
13214
13722
  init_run_ticket_number();
13723
+ init_activation_ledger_topology();
13215
13724
  init_session_identity();
13216
13725
  init_sitian_facade();
13217
13726
  init_receipt_delivery_policy();
@@ -13360,10 +13869,14 @@ function unreadablePostSubmissionStatus(admitted, terminal) {
13360
13869
  const status = receivedDiscriminator(payload, "status");
13361
13870
  return typeof status === "string" && route.statuses.has(status) ? void 0 : route.reask ?? officerConclusionReask(status);
13362
13871
  }
13872
+ function withoutSoftTicketReaskTurn(env) {
13873
+ const { softTicketReaskTurn: _softTicketReaskTurn, ...rest } = env;
13874
+ return rest;
13875
+ }
13363
13876
  function withUnreadableReask(env) {
13364
13877
  const spent = env.unreadableReasksSpent ?? 0;
13365
13878
  if (spent >= deliveryLimitFromConfig(env.autoResumeLimit)) return void 0;
13366
- return { ...env, unreadableReasksSpent: spent + 1 };
13879
+ return { ...withoutSoftTicketReaskTurn(env), unreadableReasksSpent: spent + 1 };
13367
13880
  }
13368
13881
  function isUnreadableReaskExhausted(value) {
13369
13882
  return value === UNREADABLE_REASK_EXHAUSTED;
@@ -13422,6 +13935,110 @@ async function reaskUnreadablePostSubmissionStatus(admitted, terminal, env, io,
13422
13935
  io
13423
13936
  );
13424
13937
  }
13938
+ async function reaskMissingTicketOnce(admitted, terminal, env, io) {
13939
+ if ((env.ticketReasksSpent ?? 0) >= 1) return { kind: "none" };
13940
+ if (admitted.ticketNumber !== void 0) return { kind: "none" };
13941
+ if (!isUnboundRunDirectory(admitted.runDirectory)) return { kind: "none" };
13942
+ if (terminal?.roleOutcome.kind !== "accepted" && terminal?.roleOutcome.kind !== "audit_escalation") {
13943
+ return { kind: "none" };
13944
+ }
13945
+ const payloads = terminal.roleOutcome.payloads ?? [];
13946
+ if (payloads.length === 0) return { kind: "none" };
13947
+ const instruction = (await readPackageMaterial(MISSING_TICKET_REASK_MATERIAL)).trim();
13948
+ const softTicketReaskOwnership = { sealedSubstitute: false };
13949
+ const softReaskEnv = {
13950
+ ...env,
13951
+ ticketReasksSpent: 1,
13952
+ softTicketReaskTurn: true,
13953
+ softTicketReaskOwnership
13954
+ };
13955
+ const result = await runPublicInstructionSeatResume(
13956
+ { runId: admitted.runId, summons: { instruction } },
13957
+ softReaskEnv,
13958
+ io
13959
+ );
13960
+ if (softTicketReaskOwnership.sealedSubstitute || terminalCarriesSealedSubmission(result.terminal)) {
13961
+ return { kind: "nested_owns", result };
13962
+ }
13963
+ return { kind: "no_substitute", result };
13964
+ }
13965
+ function envForCourtContinue(env) {
13966
+ return { ...withoutSoftTicketReaskTurn(env), unreadableReasksSpent: 0 };
13967
+ }
13968
+ function terminalCarriesSealedSubmission(terminal) {
13969
+ const kind = terminal?.roleOutcome.kind;
13970
+ if (kind !== "accepted" && kind !== "audit_escalation") return false;
13971
+ return (terminal?.roleOutcome.payloads ?? []).length > 0;
13972
+ }
13973
+ function projectKeptOriginalArtifactsOntoLiveAdmitted(original, kept) {
13974
+ const oldRunDirectory = original.admitted?.runDirectory;
13975
+ const newRunDirectory = kept.admitted?.runDirectory;
13976
+ if (oldRunDirectory === void 0 || newRunDirectory === void 0 || oldRunDirectory === newRunDirectory || kept.terminal === void 0) {
13977
+ return;
13978
+ }
13979
+ for (const artifact of kept.terminal.artifacts) {
13980
+ artifact.path = rewriteRunDirectoryPathValue(
13981
+ artifact.path,
13982
+ oldRunDirectory,
13983
+ newRunDirectory
13984
+ );
13985
+ }
13986
+ }
13987
+ function mergeMissingTicketReaskKeepOriginal(original, ticketReask) {
13988
+ if (ticketReask.exitCode !== 0) return ticketReask;
13989
+ const admitted = ticketReask.admitted ?? original.admitted;
13990
+ if (admitted === void 0) return { ...original };
13991
+ const kept = { ...original, admitted };
13992
+ projectKeptOriginalArtifactsOntoLiveAdmitted(original, kept);
13993
+ return kept;
13994
+ }
13995
+ async function continueAfterPostSubmissionGuards(result, admittedRole, env, io, held) {
13996
+ const live = result.admitted;
13997
+ if (live === void 0) {
13998
+ await presentOriginalVolume(held, result.terminal, io);
13999
+ return result;
14000
+ }
14001
+ const unreadableReask = await reaskUnreadablePostSubmissionStatus(
14002
+ live,
14003
+ result.terminal,
14004
+ env,
14005
+ io
14006
+ );
14007
+ let afterStatus = result;
14008
+ if (isUnreadableReaskExhausted(unreadableReask)) {
14009
+ const terminal = result.terminal === void 0 ? void 0 : withUnsettledDirection(result.terminal);
14010
+ afterStatus = terminal === void 0 ? { ...result, admitted: live } : { ...result, admitted: live, terminal };
14011
+ } else if (unreadableReask !== void 0) {
14012
+ return unreadableReask;
14013
+ }
14014
+ const forTicket = afterStatus.admitted ?? live;
14015
+ const softReask = await reaskMissingTicketOnce(
14016
+ forTicket,
14017
+ afterStatus.terminal ?? result.terminal,
14018
+ env,
14019
+ io
14020
+ );
14021
+ if (softReask.kind === "nested_owns") {
14022
+ return softReask.result;
14023
+ }
14024
+ const continued = softReask.kind === "none" ? afterStatus : mergeMissingTicketReaskKeepOriginal(afterStatus, softReask.result);
14025
+ const continuedAdmitted = continued.admitted ?? live;
14026
+ const continuedEnv = softReask.kind !== "none" ? { ...env, ticketReasksSpent: 1 } : env;
14027
+ if (AUDITED_ROLES.has(admittedRole) && continued.terminal?.roleOutcome.kind === "accepted") {
14028
+ return auditSubmittedRole(
14029
+ { ...continued, admitted: continuedAdmitted },
14030
+ continuedEnv,
14031
+ io
14032
+ );
14033
+ }
14034
+ await presentOriginalVolume(
14035
+ held,
14036
+ continued.terminal,
14037
+ io,
14038
+ continuedAdmitted.runDirectory
14039
+ );
14040
+ return { ...continued, admitted: continuedAdmitted };
14041
+ }
13425
14042
  function roleRecord(role) {
13426
14043
  const record = packagedRoleMetadata(role);
13427
14044
  if (record === void 0) {
@@ -13596,23 +14213,14 @@ async function dispatchAdmitted(admitted, env, io) {
13596
14213
  });
13597
14214
  };
13598
14215
  const result = await execute(env);
13599
- const unreadableReask = await reaskUnreadablePostSubmissionStatus(
13600
- admitted,
13601
- result.terminal,
14216
+ const live = result.admitted ?? admitted;
14217
+ return continueAfterPostSubmissionGuards(
14218
+ { ...result, admitted: live },
14219
+ admitted.role,
13602
14220
  env,
13603
- io
14221
+ io,
14222
+ held
13604
14223
  );
13605
- if (isUnreadableReaskExhausted(unreadableReask)) {
13606
- const terminal = result.terminal === void 0 ? void 0 : withUnsettledDirection(result.terminal);
13607
- await presentOriginalVolume(held, terminal, io, admitted.runDirectory);
13608
- return terminal === void 0 ? result : { ...result, terminal };
13609
- }
13610
- if (unreadableReask !== void 0) return unreadableReask;
13611
- if (AUDITED_ROLES.has(admitted.role) && result.terminal?.roleOutcome.kind === "accepted") {
13612
- return auditSubmittedRole(result, env, io);
13613
- }
13614
- await presentOriginalVolume(held, result.terminal, io, admitted.runDirectory);
13615
- return result;
13616
14224
  }
13617
14225
  async function runOmittedLensBatch(argv, parsed, env, io) {
13618
14226
  const { summonParallelReviewerLenses: summonParallelReviewerLenses2 } = await Promise.resolve().then(() => (init_public_role_summons(), public_role_summons_exports));
@@ -13798,9 +14406,7 @@ async function runPublicInstructionSeat(argv, env, io, role, parseArgv2) {
13798
14406
  stdout: (value) => held.push(value),
13799
14407
  stderr: io.stderr
13800
14408
  });
13801
- if (result.terminal?.roleOutcome.kind === "accepted") return auditSubmittedRole(result, env, io);
13802
- await presentOriginalVolume(held, result.terminal, io, result.admitted?.runDirectory);
13803
- return result;
14409
+ return continueAfterPostSubmissionGuards(result, "countersign", env, io, held);
13804
14410
  }
13805
14411
  if ("parallelLenses" in record && record.parallelLenses === true) {
13806
14412
  if (parsed.baseRevision === void 0) {
@@ -14074,23 +14680,17 @@ async function runPublicInstructionSeatResume(request, env, io) {
14074
14680
  },
14075
14681
  ...env.engine === void 0 ? {} : { effectiveEngine: env.engine }
14076
14682
  });
14077
- const unreadableReask = result.admitted === void 0 ? void 0 : await reaskUnreadablePostSubmissionStatus(
14078
- result.admitted,
14079
- result.terminal,
14683
+ if (result.admitted === void 0) {
14684
+ await presentOriginalVolume(held, result.terminal, io);
14685
+ return result;
14686
+ }
14687
+ return continueAfterPostSubmissionGuards(
14688
+ result,
14689
+ result.admitted.role,
14080
14690
  env,
14081
- io
14691
+ io,
14692
+ held
14082
14693
  );
14083
- if (isUnreadableReaskExhausted(unreadableReask)) {
14084
- const terminal = result.terminal === void 0 ? void 0 : withUnsettledDirection(result.terminal);
14085
- await presentOriginalVolume(held, terminal, io, result.admitted?.runDirectory);
14086
- return terminal === void 0 ? result : { ...result, terminal };
14087
- }
14088
- if (unreadableReask !== void 0) return unreadableReask;
14089
- if (result.admitted !== void 0 && AUDITED_ROLES.has(result.admitted.role) && result.terminal?.roleOutcome.kind === "accepted") {
14090
- return auditSubmittedRole(result, env, io);
14091
- }
14092
- await presentOriginalVolume(held, result.terminal, io, result.admitted?.runDirectory);
14093
- return result;
14094
14694
  };
14095
14695
  let binding;
14096
14696
  try {
@@ -14123,7 +14723,7 @@ async function queueConclusionFromChild(child, env, io) {
14123
14723
  return { stop: { exitCode: 0, ...terminal === void 0 ? {} : { terminal } } };
14124
14724
  }
14125
14725
  let current = child;
14126
- let budgetEnv = { ...env, unreadableReasksSpent: 0 };
14726
+ let budgetEnv = envForCourtContinue(env);
14127
14727
  for (; ; ) {
14128
14728
  const terminal = await trySettlePublicSeat(
14129
14729
  current,
@@ -14194,7 +14794,7 @@ async function continueParentAfterChild(parentRunId, child, env, io) {
14194
14794
  return runPublicInstructionSeatResume({
14195
14795
  runId: parentRunId,
14196
14796
  summons: { instruction: readableGateItem(latestQueuePayload(resolved.terminal)) }
14197
- }, { ...env, unreadableReasksSpent: 0 }, io);
14797
+ }, envForCourtContinue(env), io);
14198
14798
  }
14199
14799
  const result = await dispatchAdmitted(admitted, env, { ...io, omitFailureStderrDiagnostic: true });
14200
14800
  showResumeErrorPointer(io, result.exitCode, result.terminal);
@@ -14224,6 +14824,7 @@ async function officerPassedCurrentSubmission(input) {
14224
14824
  return latestQueueStatus(terminal) === "converged";
14225
14825
  }
14226
14826
  async function auditSubmittedRole(turn, env, io, resumedOfficer, passedReceipt) {
14827
+ env = withoutSoftTicketReaskTurn(env);
14227
14828
  const admitted = turn.admitted;
14228
14829
  if (admitted === void 0 || !AUDITED_ROLES.has(admitted.role) || turn.terminal?.roleOutcome.kind !== "accepted") return turn;
14229
14830
  const accepted = turn.terminal.roleOutcome.payloads?.at(-1);
@@ -14257,10 +14858,10 @@ async function auditSubmittedRole(turn, env, io, resumedOfficer, passedReceipt)
14257
14858
  await presentTerminal(turn.terminal, { ...io, omitFailureStderrDiagnostic: true }, admitted.runDirectory);
14258
14859
  return turn;
14259
14860
  }
14260
- const rows = await readRecordedSubmissionRows(admitted.projectRoot, admitted.runId, env.home);
14261
- const acceptedRow = [...rows].reverse().find((row) => row.role === admitted.role && row.kind === "accepted");
14262
- const toolCallId = acceptedRow?.toolCallId;
14263
- if (toolCallId === void 0) throw new Error("accepted submission has no tool call identity");
14861
+ const toolCallId = turn.terminal.submissionToolCallId;
14862
+ if (toolCallId === void 0 || toolCallId.length === 0) {
14863
+ throw new Error("accepted submission has no tool call identity");
14864
+ }
14264
14865
  const sessionFile = env.principalAuthority.decode(admitted.principal).sessionFile;
14265
14866
  const entries = admitted.role === "doctor" ? await readBoundSessionEntries(sessionFile) : [];
14266
14867
  const context = {
@@ -14326,7 +14927,7 @@ async function auditSubmittedRole(turn, env, io, resumedOfficer, passedReceipt)
14326
14927
  return runPublicInstructionSeatResume({
14327
14928
  runId: admitted.runId,
14328
14929
  summons: { instruction: readableGateItem(decision.receipt ?? decision.violations) }
14329
- }, { ...env, unreadableReasksSpent: 0 }, io);
14930
+ }, envForCourtContinue(env), io);
14330
14931
  }
14331
14932
  if (decision.status === "received") {
14332
14933
  if (lastSummon?.terminal === void 0) {
@@ -14426,7 +15027,7 @@ async function auditSubmittedRole(turn, env, io, resumedOfficer, passedReceipt)
14426
15027
  return runPublicInstructionSeatResume({
14427
15028
  runId: admitted.runId,
14428
15029
  summons: { instruction: readableGateItem(chain.passes.at(-1)?.receipt) }
14429
- }, { ...env, unreadableReasksSpent: 0 }, io);
15030
+ }, envForCourtContinue(env), io);
14430
15031
  }
14431
15032
  if (admitted.role === "secretariat") {
14432
15033
  const pass = chain.passes.at(-1);
@@ -14455,7 +15056,10 @@ var AUDITED_ROLES, SECRETARIAT_STATUS_REASK, WORKER_ROUTING_STATUSES, WORKER_STA
14455
15056
  var init_instruction_seat_run = __esm({
14456
15057
  "src/public-cli/instruction-seat-run.ts"() {
14457
15058
  "use strict";
15059
+ init_report_ticket_tool();
14458
15060
  init_role_run_placement();
15061
+ init_role_run_relocation();
15062
+ init_session_opening_materials();
14459
15063
  init_archivist_record_pointer();
14460
15064
  init_doctor_auditor();
14461
15065
  init_gatekeeper_role();
@@ -15163,7 +15767,7 @@ var init_analyst_gate_cycles_read = __esm({
15163
15767
 
15164
15768
  // src/analyst-ledger.ts
15165
15769
  import { readdir as readdir3 } from "node:fs/promises";
15166
- import { basename as basename10, join as join24 } from "node:path";
15770
+ import { basename as basename11, join as join24 } from "node:path";
15167
15771
  async function readExistingRunLifecycleState(runDirectory) {
15168
15772
  return (await readRoleRunIdentity(runDirectory))?.state;
15169
15773
  }
@@ -15515,7 +16119,7 @@ async function scanAnalystIssueRuns(input) {
15515
16119
  throw error;
15516
16120
  }
15517
16121
  for (const runDirectory of runDirectories) {
15518
- const runName = basename10(runDirectory);
16122
+ const runName = basename11(runDirectory);
15519
16123
  const parsed = parseRunLeaf(runName);
15520
16124
  if (parsed === void 0) continue;
15521
16125
  let scopeFields;
@@ -16500,7 +17104,7 @@ var init_analyst_model_groups = __esm({
16500
17104
 
16501
17105
  // src/analyst-entry.ts
16502
17106
  import { readFile as readFile12 } from "node:fs/promises";
16503
- import { Type as Type15 } from "typebox";
17107
+ import { Type as Type16 } from "typebox";
16504
17108
  function cachedPageMatchesRequestedScope(page, input) {
16505
17109
  if (page.bookKey !== input.bookKey) return false;
16506
17110
  const requestedTicket = input.ticketNumber ?? input.issueNumber;
@@ -16705,16 +17309,16 @@ var init_analyst_entry = __esm({
16705
17309
  }
16706
17310
  }
16707
17311
  };
16708
- analystSweepModeInputSchema = Type15.Object(
17312
+ analystSweepModeInputSchema = Type16.Object(
16709
17313
  {
16710
- mode: Type15.Literal("sweep"),
16711
- mergedPullRequests: Type15.Array(
16712
- Type15.Object(
17314
+ mode: Type16.Literal("sweep"),
17315
+ mergedPullRequests: Type16.Array(
17316
+ Type16.Object(
16713
17317
  {
16714
- projectRoot: Type15.String(),
17318
+ projectRoot: Type16.String(),
16715
17319
  /** 排除后改动行数 — omit or 0 → typed 空缺; finite ≥ 0 only. */
16716
- changedLines: Type15.Optional(
16717
- Type15.Number({ minimum: 0, maximum: Number.MAX_VALUE })
17320
+ changedLines: Type16.Optional(
17321
+ Type16.Number({ minimum: 0, maximum: Number.MAX_VALUE })
16718
17322
  )
16719
17323
  }
16720
17324
  )
@@ -17807,7 +18411,7 @@ __export(public_role_summons_exports, {
17807
18411
  summonPublicRole: () => summonPublicRole
17808
18412
  });
17809
18413
  import { execFile as execFile3 } from "node:child_process";
17810
- import { existsSync as existsSync8 } from "node:fs";
18414
+ import { existsSync as existsSync12 } from "node:fs";
17811
18415
  import { realpath as realpath6 } from "node:fs/promises";
17812
18416
  import { join as join26 } from "node:path";
17813
18417
  import { promisify as promisify3 } from "node:util";
@@ -17833,7 +18437,7 @@ function parentDir(path) {
17833
18437
  function walkPackageRoot(start) {
17834
18438
  let dir = start;
17835
18439
  for (let i = 0; i < 12; i += 1) {
17836
- if (existsSync8(join26(dir, "package.json")) && existsSync8(join26(dir, "souls"))) {
18440
+ if (existsSync12(join26(dir, "package.json")) && existsSync12(join26(dir, "souls"))) {
17837
18441
  return dir;
17838
18442
  }
17839
18443
  const parent = parentDir(dir);
@@ -18501,6 +19105,24 @@ function rewriteRunDirectoryPathFields(record, fields, oldRunDirectory, newRunDi
18501
19105
  { oldRunDirectory, newRunDirectory }
18502
19106
  ]);
18503
19107
  }
19108
+ function rewritePrincipalSessionPaths(principal, oldRunDirectory, newRunDirectory) {
19109
+ rewriteRunDirectoryPathFields(
19110
+ principal,
19111
+ PRINCIPAL_SESSION_PATH_FIELDS,
19112
+ oldRunDirectory,
19113
+ newRunDirectory
19114
+ );
19115
+ }
19116
+ function projectTurnRequestLiveRunDirectory(request, newRunDirectory) {
19117
+ const old = request.runDirectory;
19118
+ if (old === newRunDirectory) return;
19119
+ request.runDirectory = newRunDirectory;
19120
+ rewritePrincipalSessionPaths(
19121
+ request.principal,
19122
+ old,
19123
+ newRunDirectory
19124
+ );
19125
+ }
18504
19126
  function rewriteRunDirectoryPathFieldsAgainstRewrites(record, fields, rewrites) {
18505
19127
  for (const field of fields) {
18506
19128
  if (field in record) {
@@ -18525,12 +19147,12 @@ function rewriteAdmittedRoleRunPage(page, rewrites) {
18525
19147
  if (isRecord(page.principal)) {
18526
19148
  rewriteRunDirectoryPathFieldsAgainstRewrites(
18527
19149
  page.principal,
18528
- ["sessionDirectory", "sessionFile"],
19150
+ PRINCIPAL_SESSION_PATH_FIELDS,
18529
19151
  rewrites
18530
19152
  );
18531
19153
  }
18532
19154
  }
18533
- var ADMITTED_PAGE_FIELDS, SOURCE_RUN_LOCATOR_FIELDS;
19155
+ var ADMITTED_PAGE_FIELDS, PRINCIPAL_SESSION_PATH_FIELDS, SOURCE_RUN_LOCATOR_FIELDS;
18534
19156
  var init_role_run_relocation = __esm({
18535
19157
  "src/role-run-relocation.ts"() {
18536
19158
  "use strict";
@@ -18552,6 +19174,10 @@ var init_role_run_relocation = __esm({
18552
19174
  "mergerInputPath",
18553
19175
  "sourceRunPath"
18554
19176
  ];
19177
+ PRINCIPAL_SESSION_PATH_FIELDS = [
19178
+ "sessionDirectory",
19179
+ "sessionFile"
19180
+ ];
18555
19181
  SOURCE_RUN_LOCATOR_FIELDS = ["runDirectory"];
18556
19182
  }
18557
19183
  });
@@ -18582,7 +19208,7 @@ __export(run_lifecycle_exports, {
18582
19208
  writeRoleRunState: () => writeRoleRunState
18583
19209
  });
18584
19210
  import { chmod, lstat as lstat3, open as open2, readdir as readdir4, readFile as readFile14, unlink as unlink2 } from "node:fs/promises";
18585
- import { basename as basename11, join as join28 } from "node:path";
19211
+ import { basename as basename12, join as join28 } from "node:path";
18586
19212
  function buildAutoResumeContinuationPrompt() {
18587
19213
  return RESUME_TRANSPORT_ENVELOPE;
18588
19214
  }
@@ -19029,7 +19655,7 @@ async function findLatestRunIdForSeatTicket(input) {
19029
19655
  }
19030
19656
  let best;
19031
19657
  for (const runDirectory of runDirectories) {
19032
- const parsed = parseRunLeaf(basename11(runDirectory));
19658
+ const parsed = parseRunLeaf(basename12(runDirectory));
19033
19659
  if (parsed === void 0 || parsed.role !== input.role) continue;
19034
19660
  const runId = parsed.runId;
19035
19661
  const parentPath = await readRunParentPath(runDirectory);
@@ -19224,7 +19850,7 @@ async function loadResumableRunRecord(home, runId, authority) {
19224
19850
  );
19225
19851
  }
19226
19852
  }
19227
- const sourceRunLeaf = parseRunLeaf(basename11(sourceRunPath ?? ""));
19853
+ const sourceRunLeaf = parseRunLeaf(basename12(sourceRunPath ?? ""));
19228
19854
  const referencedRunId = sourceRun?.runId ?? sourceRunLeaf?.runId;
19229
19855
  const referencedRole = sourceRun?.role ?? sourceRunLeaf?.role;
19230
19856
  if (referencedRunId !== void 0 && referencedRunId !== "") {
@@ -19795,7 +20421,7 @@ var init_archivist_record_topology = __esm({
19795
20421
  });
19796
20422
 
19797
20423
  // src/pi/record-session-host.ts
19798
- import { existsSync as existsSync10 } from "node:fs";
20424
+ import { existsSync as existsSync14 } from "node:fs";
19799
20425
  import { SessionManager } from "@earendil-works/pi-coding-agent";
19800
20426
  var piRecordSessionHost;
19801
20427
  var init_record_session_host = __esm({
@@ -19817,7 +20443,7 @@ var init_record_session_host = __esm({
19817
20443
  const sessionFile = session.getSessionFile();
19818
20444
  return {
19819
20445
  session,
19820
- resumed: sessionFile !== void 0 && existsSync10(sessionFile)
20446
+ resumed: sessionFile !== void 0 && existsSync14(sessionFile)
19821
20447
  };
19822
20448
  },
19823
20449
  inMemoryRecordSession(cwd) {
@@ -19840,7 +20466,7 @@ __export(archivist_record_entry_exports, {
19840
20466
  });
19841
20467
  import {
19842
20468
  closeSync,
19843
- existsSync as existsSync11,
20469
+ existsSync as existsSync15,
19844
20470
  openSync,
19845
20471
  readdirSync as readdirSync3,
19846
20472
  readFileSync as readFileSync4,
@@ -20001,7 +20627,7 @@ function mostRecentNavigatorSessionFile(sessionDir, cwd) {
20001
20627
  }
20002
20628
  function resolveNavigatorNestContinuation(sessionDir, cwd) {
20003
20629
  const ledgerPath = currentSessionLedgerPath(sessionDir);
20004
- if (existsSync11(ledgerPath)) {
20630
+ if (existsSync15(ledgerPath)) {
20005
20631
  const recentFile = readCurrentSession(sessionDir);
20006
20632
  assertRecentFinalFileUnderSessionDir(sessionDir, recentFile);
20007
20633
  return recentFile;
@@ -20086,7 +20712,7 @@ function createRecordSessionOpen(options, host = piRecordSessionHost) {
20086
20712
  parentSession = parentFile;
20087
20713
  mayResumeSameNest = options.kind === WORKER_SUBMISSION_GATE_KIND;
20088
20714
  }
20089
- const nestAlreadyExists = existsSync11(sessionDir);
20715
+ const nestAlreadyExists = existsSync15(sessionDir);
20090
20716
  ensureRealDirectoryTree(ledgerHome, sessionDir);
20091
20717
  if (mayResumeSameNest && nestAlreadyExists) {
20092
20718
  if (options.kind === NAVIGATOR_RECORD_KIND) {
@@ -20111,7 +20737,7 @@ function createRecordSessionOpen(options, host = piRecordSessionHost) {
20111
20737
  });
20112
20738
  if (session.isPersisted()) {
20113
20739
  const file = session.getSessionFile();
20114
- if (file !== void 0 && !existsSync11(file)) {
20740
+ if (file !== void 0 && !existsSync15(file)) {
20115
20741
  const header = session.getHeader();
20116
20742
  if (header !== null && header.type === "session") {
20117
20743
  writeFileSync3(file, `${JSON.stringify(header)}
@@ -20167,24 +20793,25 @@ init_sitian_facade();
20167
20793
  init_host_session_record();
20168
20794
  init_submission_ledger();
20169
20795
  init_filed_submission();
20796
+ init_report_ticket_tool();
20170
20797
  import { randomUUID as randomUUID7 } from "node:crypto";
20171
20798
  import { writeSync as writeSync2 } from "node:fs";
20172
20799
  import { join as join33 } from "node:path";
20173
20800
  import { Value as Value3 } from "typebox/value";
20174
20801
 
20175
20802
  // src/activation-trace.ts
20176
- import { Type as Type16 } from "typebox";
20177
- var causeSchema = Type16.Object({
20178
- identity: Type16.String({ minLength: 1 }),
20179
- name: Type16.String({ minLength: 1 }),
20180
- message: Type16.String(),
20181
- evidenceId: Type16.Optional(Type16.String({ minLength: 1 }))
20803
+ import { Type as Type17 } from "typebox";
20804
+ var causeSchema = Type17.Object({
20805
+ identity: Type17.String({ minLength: 1 }),
20806
+ name: Type17.String({ minLength: 1 }),
20807
+ message: Type17.String(),
20808
+ evidenceId: Type17.Optional(Type17.String({ minLength: 1 }))
20182
20809
  }, { additionalProperties: false });
20183
- var activationTraceRecordSchema = Type16.Object({
20184
- role: Type16.String({ minLength: 1 }),
20185
- stageId: Type16.String({ pattern: "^[a-z][a-z0-9-]*$" }),
20186
- status: Type16.Literal("failed"),
20187
- timestamp: Type16.String({ format: "date-time" }),
20810
+ var activationTraceRecordSchema = Type17.Object({
20811
+ role: Type17.String({ minLength: 1 }),
20812
+ stageId: Type17.String({ pattern: "^[a-z][a-z0-9-]*$" }),
20813
+ status: Type17.Literal("failed"),
20814
+ timestamp: Type17.String({ format: "date-time" }),
20188
20815
  cause: causeSchema
20189
20816
  }, { additionalProperties: false });
20190
20817
  var activationCauseEvidence = 0;
@@ -20349,10 +20976,10 @@ init_engine_material();
20349
20976
  init_engine_detour();
20350
20977
  init_engine_detour_usage();
20351
20978
  init_run_terminal_artifacts();
20352
- import { Type as Type17 } from "typebox";
20353
- var engineDetourArgsSchema = Type17.Object(
20979
+ import { Type as Type18 } from "typebox";
20980
+ var engineDetourArgsSchema = Type18.Object(
20354
20981
  {
20355
- argv: Type17.Array(Type17.String({ minLength: 1 }), {
20982
+ argv: Type18.Array(Type18.String({ minLength: 1 }), {
20356
20983
  minItems: 1,
20357
20984
  description: "\u9996\u9879\u4E3A PATH \u4E2D\u7684\u53EF\u6267\u884C\u6587\u4EF6\uFF0C\u5176\u4F59\u9879\u4E3A\u53C2\u6570\u3002"
20358
20985
  })
@@ -20676,10 +21303,10 @@ init_run_ticket_number();
20676
21303
 
20677
21304
  // src/audited-run-identity.ts
20678
21305
  init_role_run_placement();
20679
- import { basename as basename12 } from "node:path";
21306
+ import { basename as basename13 } from "node:path";
20680
21307
  var AUDITED_RUN_IDENTITY_KIND = "audited-run-identity";
20681
21308
  function auditedRunIdentityFromDirectory(runDirectory) {
20682
- const parsed = parseRunLeaf(basename12(runDirectory));
21309
+ const parsed = parseRunLeaf(basename13(runDirectory));
20683
21310
  if (parsed === void 0) return void 0;
20684
21311
  return formatRunLeaf(parsed.runId, parsed.role);
20685
21312
  }
@@ -20855,16 +21482,16 @@ init_packaged_role_registry();
20855
21482
  init_activation_ledger_topology();
20856
21483
  import { resolve as resolve17 } from "node:path";
20857
21484
  import "@earendil-works/pi-coding-agent";
20858
- import { Type as Type19 } from "typebox";
21485
+ import { Type as Type20 } from "typebox";
20859
21486
 
20860
21487
  // src/navigator-public-session.ts
20861
21488
  init_host_session_record();
20862
- import { existsSync as existsSync12 } from "node:fs";
20863
- import { basename as basename14 } from "node:path";
21489
+ import { existsSync as existsSync16 } from "node:fs";
21490
+ import { basename as basename15 } from "node:path";
20864
21491
 
20865
21492
  // src/navigator-session-contracts.ts
20866
21493
  init_unknown_value();
20867
- import { Type as Type18 } from "typebox";
21494
+ import { Type as Type19 } from "typebox";
20868
21495
  import { Value as Value2 } from "typebox/value";
20869
21496
  var NAVIGATOR_PREPARE_TOOL_NAME = "ak_navigator_prepare";
20870
21497
  var NAVIGATOR_UNAVAILABLE_KEYS = /* @__PURE__ */ new Set([
@@ -20969,26 +21596,26 @@ function navigatorProviderFailureFromPublicTerminal(outcome) {
20969
21596
  if (typed !== void 0) return { source: typed, cause: typed };
20970
21597
  return { source: "unknown", cause: "unknown" };
20971
21598
  }
20972
- var navigatorProviderFailureSchema = Type18.Object({
20973
- source: Type18.Union([
20974
- Type18.Literal("context"),
20975
- Type18.Literal("session"),
20976
- Type18.Literal("model"),
20977
- Type18.Literal("thinking"),
20978
- Type18.Literal("auth"),
20979
- Type18.Literal("quota"),
20980
- Type18.Literal("transport"),
20981
- Type18.Literal("unknown")
21599
+ var navigatorProviderFailureSchema = Type19.Object({
21600
+ source: Type19.Union([
21601
+ Type19.Literal("context"),
21602
+ Type19.Literal("session"),
21603
+ Type19.Literal("model"),
21604
+ Type19.Literal("thinking"),
21605
+ Type19.Literal("auth"),
21606
+ Type19.Literal("quota"),
21607
+ Type19.Literal("transport"),
21608
+ Type19.Literal("unknown")
20982
21609
  ]),
20983
- cause: Type18.Union([
20984
- Type18.Literal("context"),
20985
- Type18.Literal("session"),
20986
- Type18.Literal("model"),
20987
- Type18.Literal("thinking"),
20988
- Type18.Literal("auth"),
20989
- Type18.Literal("quota"),
20990
- Type18.Literal("transport"),
20991
- Type18.Literal("unknown")
21610
+ cause: Type19.Union([
21611
+ Type19.Literal("context"),
21612
+ Type19.Literal("session"),
21613
+ Type19.Literal("model"),
21614
+ Type19.Literal("thinking"),
21615
+ Type19.Literal("auth"),
21616
+ Type19.Literal("quota"),
21617
+ Type19.Literal("transport"),
21618
+ Type19.Literal("unknown")
20992
21619
  ])
20993
21620
  }, { additionalProperties: false });
20994
21621
  function parseNavigatorModelSetting(value) {
@@ -21053,9 +21680,9 @@ init_packaged_role_registry();
21053
21680
  // src/navigator-work-base.ts
21054
21681
  init_atomic_write();
21055
21682
  init_unknown_value();
21056
- import { existsSync as existsSync9, realpathSync as realpathSync3 } from "node:fs";
21683
+ import { existsSync as existsSync13, realpathSync as realpathSync3 } from "node:fs";
21057
21684
  import { readFile as readFile15 } from "node:fs/promises";
21058
- import { basename as basename13, dirname as dirname18, join as join29, resolve as resolve15 } from "node:path";
21685
+ import { basename as basename14, dirname as dirname18, join as join29, resolve as resolve15 } from "node:path";
21059
21686
  var NAVIGATOR_WORK_CONTEXT_BASENAME = "work-context.json";
21060
21687
  var AK_ROLE_NAVIGATOR_WORK_CONTEXT_ENV = "AK_ROLE_NAVIGATOR_WORK_CONTEXT";
21061
21688
  function navigatorWorkContextFile(sessionDir) {
@@ -21063,10 +21690,10 @@ function navigatorWorkContextFile(sessionDir) {
21063
21690
  }
21064
21691
  function isNavigatorWorkContextFile(path) {
21065
21692
  const resolved = resolve15(path);
21066
- if (basename13(resolved) !== NAVIGATOR_WORK_CONTEXT_BASENAME) return false;
21693
+ if (basename14(resolved) !== NAVIGATOR_WORK_CONTEXT_BASENAME) return false;
21067
21694
  const nest = dirname18(resolved);
21068
- if (!/^[0-9a-f]{32}$/.test(basename13(nest))) return false;
21069
- return basename13(dirname18(nest)) === "navigator";
21695
+ if (!/^[0-9a-f]{32}$/.test(basename14(nest))) return false;
21696
+ return basename14(dirname18(nest)) === "navigator";
21070
21697
  }
21071
21698
  function canonicalNavigatorWorkContextFile(path) {
21072
21699
  if (!isNavigatorWorkContextFile(path)) return void 0;
@@ -21078,7 +21705,7 @@ function canonicalNavigatorWorkContextFile(path) {
21078
21705
  }
21079
21706
  }
21080
21707
  async function persistNavigatorWorkBase(sessionDir, body) {
21081
- if (sessionDir.trim() === "" || !existsSync9(sessionDir)) return void 0;
21708
+ if (sessionDir.trim() === "" || !existsSync13(sessionDir)) return void 0;
21082
21709
  if (body.authority.trim() === "") return void 0;
21083
21710
  const path = navigatorWorkContextFile(sessionDir);
21084
21711
  const next = `${JSON.stringify({ subject: body.subject, authority: body.authority })}
@@ -21146,7 +21773,7 @@ async function resolveNavigatorLedgerHome(context) {
21146
21773
  }
21147
21774
  var NAVIGATOR_HOST_RUN_POINTER_ENTRY = "ak-navigator-host-run";
21148
21775
  function runIdFromNavigatorDirectory(runDirectory) {
21149
- const parsed = parseRunLeaf(basename14(runDirectory));
21776
+ const parsed = parseRunLeaf(basename15(runDirectory));
21150
21777
  if (parsed === void 0 || parsed.role !== "navigator") return void 0;
21151
21778
  return parsed.runId;
21152
21779
  }
@@ -21208,7 +21835,7 @@ function createNativeNavigatorSessionFactory(deps) {
21208
21835
  if (disposed) return;
21209
21836
  const resumeRunId = hostRunId;
21210
21837
  const workContextPath = navigatorWorkContextFile(sessionManager.getSessionDir());
21211
- const workContextLocator = existsSync12(workContextPath) ? workContextPath : void 0;
21838
+ const workContextLocator = existsSync16(workContextPath) ? workContextPath : void 0;
21212
21839
  const baseSummon = {
21213
21840
  role: "navigator",
21214
21841
  argv: [text],
@@ -21343,8 +21970,8 @@ function resolveNavigatorAuthorityMaterial(roleInput, fileAuthority) {
21343
21970
  return void 0;
21344
21971
  }
21345
21972
  var NAVIGATOR_TARGETS = PACKAGED_ROLE_REGISTRY.map(({ role, phases }) => ({ role, phases }));
21346
- var prepareSchema = Type19.Object({
21347
- prose: Type19.Optional(Type19.Unknown({
21973
+ var prepareSchema = Type20.Object({
21974
+ prose: Type20.Optional(Type20.Unknown({
21348
21975
  description: "\u6E38\u5955\u4F7F\u6563\u6587\u5EFA\u8BAE\uFF0C\u539F\u6837\u5448\u73B0\u3002\u4E0D\u8981\u6C42 candidates/next \u7ED3\u6784\u3002"
21349
21976
  }))
21350
21977
  }, { additionalProperties: true });
@@ -21828,7 +22455,7 @@ init_unknown_value();
21828
22455
  init_submission_errors();
21829
22456
  init_worker_submission_contracts();
21830
22457
  import { execFileSync as execFileSync3 } from "node:child_process";
21831
- import { existsSync as existsSync13, lstatSync as lstatSync3, readdirSync as readdirSync4, readFileSync as readFileSync5, rmdirSync, rmSync as rmSync3 } from "node:fs";
22458
+ import { existsSync as existsSync17, lstatSync as lstatSync3, readdirSync as readdirSync4, readFileSync as readFileSync5, rmdirSync, rmSync as rmSync3 } from "node:fs";
21832
22459
  import { resolve as resolve18 } from "node:path";
21833
22460
  var WORKER_SUBMISSION_GATE_RECORD_KIND = WORKER_SUBMISSION_GATE_KIND;
21834
22461
  var WORKER_COMMIT_BASELINE_ENTRY_TYPE = "commit-baseline";
@@ -21858,7 +22485,7 @@ function statusOf(error) {
21858
22485
  return typeof error === "object" && error !== null && "status" in error ? error.status : void 0;
21859
22486
  }
21860
22487
  function tryGetAll(file, key) {
21861
- if (!existsSync13(file)) return [];
22488
+ if (!existsSync17(file)) return [];
21862
22489
  try {
21863
22490
  const out = gitFile(file, ["--get-all", key]);
21864
22491
  return out.length === 0 ? [] : out.split("\n");
@@ -21868,7 +22495,7 @@ function tryGetAll(file, key) {
21868
22495
  }
21869
22496
  }
21870
22497
  function ownedHook(path) {
21871
- if (!existsSync13(path)) return false;
22498
+ if (!existsSync17(path)) return false;
21872
22499
  return readFileSync5(path, "utf8").includes(HOOK_MARKER);
21873
22500
  }
21874
22501
  function escapeGitConfigValueRegex(value) {
@@ -21895,11 +22522,11 @@ function rmOwnedDir(dir) {
21895
22522
  const hookPath = resolve18(dir, HOOK_FILE);
21896
22523
  if (!ownedHook(hookPath)) return;
21897
22524
  rmSync3(hookPath, { force: true });
21898
- if (existsSync13(dir) && readdirSync4(dir).length === 0) rmdirSync(dir);
22525
+ if (existsSync17(dir) && readdirSync4(dir).length === 0) rmdirSync(dir);
21899
22526
  }
21900
22527
  function linkedGitDirs(commonDir) {
21901
22528
  const root = resolve18(commonDir, "worktrees");
21902
- if (!existsSync13(root)) return [];
22529
+ if (!existsSync17(root)) return [];
21903
22530
  return readdirSync4(root).map((name) => resolve18(root, name)).filter((dir) => lstatSync3(dir).isDirectory());
21904
22531
  }
21905
22532
  function uninstallPackageWorkerHooks(cwd) {
@@ -21991,6 +22618,7 @@ function createWorkerSubmissionGate(options = {}) {
21991
22618
  let unfinishedReasonBounces = 0;
21992
22619
  let invocationScopeId;
21993
22620
  let record;
22621
+ let parentRef;
21994
22622
  let sessionParent;
21995
22623
  const explicitHome = typeof options.home === "string" && options.home.length > 0 ? options.home : void 0;
21996
22624
  const unfinishedReasonBounceLimit = deliveryLimitFromConfig(options.unfinishedReasonBounceLimit);
@@ -22002,6 +22630,20 @@ function createWorkerSubmissionGate(options = {}) {
22002
22630
  return null;
22003
22631
  }
22004
22632
  };
22633
+ const liveRecord = () => {
22634
+ if (record === void 0 || root === void 0 || parentRef === void 0) return record;
22635
+ const file = record.getSessionFile();
22636
+ if (file !== void 0 && existsSync17(file)) return record;
22637
+ const parentFile = parentRef.getSessionFile();
22638
+ if (parentFile === void 0 || parentFile.length === 0) return record;
22639
+ sessionParent = parentFile;
22640
+ record = createRecordSession({
22641
+ cwd: root,
22642
+ kind: WORKER_SUBMISSION_GATE_RECORD_KIND,
22643
+ parent: parentRef
22644
+ });
22645
+ return record;
22646
+ };
22005
22647
  const gateSitian = (cwd, payload) => {
22006
22648
  sitianReport({
22007
22649
  level: "event",
@@ -22018,6 +22660,7 @@ function createWorkerSubmissionGate(options = {}) {
22018
22660
  invocationScopeId = scope;
22019
22661
  uninstallPackageWorkerHooks(cwd);
22020
22662
  root = cwd;
22663
+ parentRef = parent;
22021
22664
  sessionParent = parent.getSessionFile();
22022
22665
  record = createRecordSession({
22023
22666
  cwd,
@@ -22046,9 +22689,10 @@ function createWorkerSubmissionGate(options = {}) {
22046
22689
  });
22047
22690
  },
22048
22691
  assertAcceptable(status, details) {
22692
+ const gateRecord = liveRecord();
22049
22693
  if (status === "unfinished" && !unfinishedReasonPresent(details)) {
22050
22694
  if (unfinishedReasonBounces < unfinishedReasonBounceLimit) {
22051
- record?.appendCustomEntry(WORKER_UNFINISHED_REASON_BOUNCE_ENTRY_TYPE, {
22695
+ gateRecord?.appendCustomEntry(WORKER_UNFINISHED_REASON_BOUNCE_ENTRY_TYPE, {
22052
22696
  version: 1,
22053
22697
  invocationScopeId
22054
22698
  });
@@ -22061,7 +22705,7 @@ function createWorkerSubmissionGate(options = {}) {
22061
22705
  const headMoved = now !== null && (baseline === null || now !== baseline);
22062
22706
  if (!headMoved && !reminded) {
22063
22707
  reminded = true;
22064
- record?.appendCustomEntry(WORKER_COMMIT_REMINDER_BOUNCE_ENTRY_TYPE, { version: 1 });
22708
+ gateRecord?.appendCustomEntry(WORKER_COMMIT_REMINDER_BOUNCE_ENTRY_TYPE, { version: 1 });
22065
22709
  gateSitian(root, {
22066
22710
  type: WORKER_COMMIT_REMINDER_BOUNCE_ENTRY_TYPE,
22067
22711
  version: 1
@@ -22075,7 +22719,7 @@ function createWorkerSubmissionGate(options = {}) {
22075
22719
  return;
22076
22720
  }
22077
22721
  prefixReminded = true;
22078
- record?.appendCustomEntry(WORKER_PREFIX_REMINDER_BOUNCE_ENTRY_TYPE, { version: 1 });
22722
+ gateRecord?.appendCustomEntry(WORKER_PREFIX_REMINDER_BOUNCE_ENTRY_TYPE, { version: 1 });
22079
22723
  gateSitian(root, {
22080
22724
  type: WORKER_PREFIX_REMINDER_BOUNCE_ENTRY_TYPE,
22081
22725
  version: 1
@@ -23541,6 +24185,10 @@ function createRoleRuntimeExtension(dependencies, deliveryRequestLimit) {
23541
24185
  }
23542
24186
  }
23543
24187
  await executeActivationStage(entry.role, activationStage(entry.role, activateByRole), { clock, writeTrace });
24188
+ registerReportTicketTool(roleHost);
24189
+ roleHost.setActiveTools([
24190
+ .../* @__PURE__ */ new Set([...roleHost.getActiveTools(), REPORT_TICKET_TOOL_NAME])
24191
+ ]);
23544
24192
  roleReferenceMaterials = await dependencies.loadRoleReferenceMaterials?.(entry.role) ?? "";
23545
24193
  if (!engineDetourRegistered) {
23546
24194
  engineDetourRegistered = registerEngineDetourTool(roleHost, hostActions);
@@ -23564,6 +24212,7 @@ function createRoleRuntimeExtension(dependencies, deliveryRequestLimit) {
23564
24212
 
23565
24213
  // src/role-envelope.ts
23566
24214
  init_role_activation_flags();
24215
+ init_role_run_relocation();
23567
24216
  init_submission_correctable_error();
23568
24217
  init_navigator_invocation_identity();
23569
24218
  init_serialize_thrown_value();
@@ -23649,11 +24298,11 @@ async function prepareRoleEnvelope(options) {
23649
24298
  }
23650
24299
  });
23651
24300
  };
24301
+ const mutableRequest = request;
23652
24302
  const context = {
23653
24303
  cwd: request.cwd,
23654
24304
  mode: "print",
23655
24305
  model: request.model === void 0 ? void 0 : { provider: request.model.provider },
23656
- runDirectory: request.runDirectory,
23657
24306
  ...request.courtAttemptId === void 0 ? {} : { courtAttemptId: request.courtAttemptId },
23658
24307
  ...request.invocationScopeId === void 0 ? {} : { invocationScopeId: request.invocationScopeId },
23659
24308
  ...request.host === void 0 || request.host.trim() === "" ? {} : { host: request.host.trim() },
@@ -23678,6 +24327,25 @@ async function prepareRoleEnvelope(options) {
23678
24327
  abort() {
23679
24328
  }
23680
24329
  };
24330
+ Object.defineProperty(context, "runDirectory", {
24331
+ configurable: true,
24332
+ enumerable: true,
24333
+ get() {
24334
+ return mutableRequest.runDirectory;
24335
+ },
24336
+ set(next) {
24337
+ if (typeof next !== "string" || next.trim() === "") return;
24338
+ if (mutableRequest.runDirectory === next) return;
24339
+ projectTurnRequestLiveRunDirectory(mutableRequest, next);
24340
+ sessionFile = sessionFileOf(next);
24341
+ if (typeof mutableRequest.principal.sessionDirectory !== "string") {
24342
+ mutableRequest.principal.sessionDirectory = sessionDirectoryOf(next);
24343
+ }
24344
+ if (typeof mutableRequest.principal.sessionFile !== "string") {
24345
+ mutableRequest.principal.sessionFile = sessionFile;
24346
+ }
24347
+ }
24348
+ });
23681
24349
  const bookCustomMessage = (customType, message) => {
23682
24350
  const payload = {
23683
24351
  ...message.content === void 0 ? {} : { content: message.content },
@@ -24006,7 +24674,7 @@ async function prepareRoleEnvelope(options) {
24006
24674
  });
24007
24675
  } catch (error) {
24008
24676
  await retainPackageFault({
24009
- runDirectory: request.runDirectory,
24677
+ runDirectory: mutableRequest.runDirectory,
24010
24678
  diagnostic: `relay close failed beside envelope shutdown: ${describeErrorIdentity(error)}`,
24011
24679
  error
24012
24680
  });
@@ -24304,191 +24972,13 @@ function acpModelId(description, model) {
24304
24972
 
24305
24973
  // src/acp-host/role-turn-host.ts
24306
24974
  init_role_run_placement();
24307
- import { spawn as spawn3 } from "node:child_process";
24308
- import { createInterface } from "node:readline";
24309
-
24310
- // src/external-host-turn-loop.ts
24311
- init_settlement();
24312
- init_run_lifecycle();
24313
- init_receipt_delivery_policy();
24314
- init_sitian_facade();
24315
- init_submission_errors();
24316
- async function recordTurnDelivery(runDirectory, delivered, source) {
24317
- try {
24318
- reportRunRecord(runDirectory, "turn-delivery", {
24319
- systemPrompt: delivered.systemPrompt,
24320
- ...delivered.outputSchema === void 0 ? {} : { outputSchema: delivered.outputSchema }
24321
- }, source);
24322
- } catch (error) {
24323
- await retainPackageFault({
24324
- runDirectory,
24325
- diagnostic: `turn delivery record failed beside host start: ${describeErrorIdentity(error)}`,
24326
- error
24327
- });
24328
- }
24329
- }
24330
- function mergeRoleTurnAbortSignals(prepared, request) {
24331
- if (request === void 0) return prepared;
24332
- if (prepared === void 0) return request;
24333
- return AbortSignal.any([prepared, request]);
24334
- }
24335
- function isHostAbortedError(error) {
24336
- return typeof error === "object" && error !== null && error.code === "host-aborted";
24337
- }
24338
- function hostAbortedError(message = "host aborted") {
24339
- return Object.assign(new Error(message), { code: "host-aborted" });
24340
- }
24341
- function raceAgainstHostAbort(work, abortSignal, message = "host aborted") {
24342
- if (abortSignal?.aborted) return Promise.reject(hostAbortedError(message));
24343
- if (abortSignal === void 0) return work;
24344
- return new Promise((resolve21, reject) => {
24345
- let settled = false;
24346
- const onAbort = () => {
24347
- if (settled) return;
24348
- settled = true;
24349
- work.catch(() => {
24350
- });
24351
- reject(hostAbortedError(message));
24352
- };
24353
- abortSignal.addEventListener("abort", onAbort, { once: true });
24354
- work.then(
24355
- (value) => {
24356
- if (settled) return;
24357
- settled = true;
24358
- abortSignal.removeEventListener("abort", onAbort);
24359
- resolve21(value);
24360
- },
24361
- (error) => {
24362
- if (settled) return;
24363
- settled = true;
24364
- abortSignal.removeEventListener("abort", onAbort);
24365
- reject(error);
24366
- }
24367
- );
24368
- });
24369
- }
24370
- function externalHostFailure(cause, name, code, details, diagnostic) {
24371
- return asFailure({
24372
- cause,
24373
- identity: { name, code },
24374
- ...diagnostic === void 0 ? {} : { diagnostic },
24375
- ...details === void 0 ? {} : { details }
24376
- });
24377
- }
24378
- function asFailure(knownFailure, stderr = "") {
24379
- return { code: null, stderr, timedOut: false, knownFailure };
24380
- }
24381
- async function settleHostAborted(prepared, sessionId) {
24382
- const closure = await prepared.closeRound();
24383
- if ("failure" in closure) return asFailure(closure.failure);
24384
- return asFailure({
24385
- cause: "session",
24386
- identity: { name: "HostAborted", code: "host-aborted" },
24387
- ...sessionId === void 0 ? {} : { details: { sessionId } }
24388
- });
24389
- }
24390
- async function driveExternalRoleTurnRounds(prepared, request, driver) {
24391
- let prompt = prepared.prompt;
24392
- const abortSignal = mergeRoleTurnAbortSignals(prepared.abortSignal, request.signal);
24393
- let result = { code: 0, stderr: "", timedOut: false };
24394
- const countedReaskLimit = deliveryLimitFromConfig(request.deliveryRequestLimit);
24395
- const exemptReminders = /* @__PURE__ */ new Set();
24396
- let countedReasks = 0;
24397
- for (let attempt = 0; ; attempt += 1) {
24398
- if (abortSignal?.aborted) return settleHostAborted(prepared, driver.currentSessionId());
24399
- let round;
24400
- try {
24401
- round = await driver.runRound({ prompt, abortSignal, attempt });
24402
- } catch (error) {
24403
- if (isHostAbortedError(error)) return settleHostAborted(prepared, driver.currentSessionId());
24404
- throw error;
24405
- }
24406
- if (round.status === "terminal") return round.result;
24407
- result = {
24408
- code: round.code !== void 0 ? round.code : 0,
24409
- stderr: round.stderr ?? "",
24410
- timedOut: round.timedOut === true,
24411
- ...round.signal === void 0 ? {} : { signal: round.signal }
24412
- };
24413
- let closure;
24414
- try {
24415
- closure = await prepared.closeRound();
24416
- } catch (error) {
24417
- await retainPackageFault({
24418
- runDirectory: request.runDirectory,
24419
- diagnostic: `round closure failed beside host terminal: ${describeErrorIdentity(error)}`,
24420
- error
24421
- });
24422
- return result.code === 0 && !result.timedOut && result.signal === void 0 ? { ...result, knownFailure: projectThrownFailureLeaf(error) } : result;
24423
- }
24424
- if (closure.accepted) {
24425
- try {
24426
- await driver.afterAccepted?.();
24427
- } catch (error) {
24428
- await retainPackageFault({
24429
- runDirectory: request.runDirectory,
24430
- diagnostic: `post-acceptance close failed beside host terminal: ${describeErrorIdentity(error)}`,
24431
- error
24432
- });
24433
- }
24434
- return result;
24435
- }
24436
- if ("failure" in closure) {
24437
- await retainPackageFault({
24438
- runDirectory: request.runDirectory,
24439
- diagnostic: `round closure failed beside host terminal: ${JSON.stringify(closure.failure)}`
24440
- });
24441
- return result.code === 0 && !result.timedOut && result.signal === void 0 ? { ...result, knownFailure: closure.failure } : result;
24442
- }
24443
- if (result.code !== 0 || result.signal !== void 0 || result.timedOut) return result;
24444
- const reminderCode = closure.retry.code;
24445
- const exempt = isOneShotWorkerReminderCode(reminderCode) && !exemptReminders.has(reminderCode);
24446
- if (exempt) exemptReminders.add(reminderCode);
24447
- else {
24448
- countedReasks += 1;
24449
- if (countedReasks > countedReaskLimit) {
24450
- await retainPackageFault({
24451
- runDirectory: request.runDirectory,
24452
- diagnostic: `${driver.roundLimitName}: round-retry-limit`
24453
- });
24454
- return result;
24455
- }
24456
- }
24457
- prompt = closure.retry.message;
24458
- driver.afterRetry?.();
24459
- }
24460
- }
24461
- async function disposeExternalRoleTurn(prepared, request, outcome) {
24462
- try {
24463
- await prepared.dispose?.();
24464
- } catch (error) {
24465
- await retainPackageFault({
24466
- runDirectory: request.runDirectory,
24467
- diagnostic: `required envelope shutdown failed beside host terminal: ${describeErrorIdentity(error)}`,
24468
- error
24469
- });
24470
- if (outcome.code === 0 && !outcome.timedOut && outcome.signal === void 0 && outcome.knownFailure === void 0) {
24471
- return { ...outcome, knownFailure: projectThrownFailureLeaf(error) };
24472
- }
24473
- }
24474
- return outcome;
24475
- }
24476
- function createSerializedRoleTurnHost(execute) {
24477
- let serial = Promise.resolve();
24478
- return {
24479
- executeTurn(request) {
24480
- const execution = serial.then(() => execute(request));
24481
- serial = execution.then(() => void 0, () => void 0);
24482
- return execution;
24483
- }
24484
- };
24485
- }
24486
-
24487
- // src/acp-host/role-turn-host.ts
24975
+ init_external_host_turn_loop();
24488
24976
  init_run_lifecycle();
24489
24977
  init_settlement();
24490
24978
  init_host_session_record();
24491
24979
  init_navigator_output();
24980
+ import { spawn as spawn3 } from "node:child_process";
24981
+ import { createInterface } from "node:readline";
24492
24982
 
24493
24983
  // src/agent-start-materials.ts
24494
24984
  function renderAgentStartMaterials(body, materials) {
@@ -24675,7 +25165,7 @@ function createAcpRoleTurnHost(config) {
24675
25165
  let sessionId;
24676
25166
  let sessionOpened = false;
24677
25167
  let accepted = false;
24678
- const sessionParent = config.sessionIdentity.resolveSessionFile(request.principal);
25168
+ const liveSessionParent = () => config.sessionIdentity.resolveSessionFile(request.principal);
24679
25169
  let outcome = externalHostFailure("session", "AcpNoOutcome", "no-outcome");
24680
25170
  let reportedFailure;
24681
25171
  let packageFailure;
@@ -24722,7 +25212,7 @@ function createAcpRoleTurnHost(config) {
24722
25212
  host: config.hostName,
24723
25213
  sessionId: loadedId,
24724
25214
  cwd: request.cwd,
24725
- sessionParent,
25215
+ sessionParent: liveSessionParent(),
24726
25216
  home: request.home
24727
25217
  });
24728
25218
  return loadedId;
@@ -24755,7 +25245,7 @@ function createAcpRoleTurnHost(config) {
24755
25245
  host: config.hostName,
24756
25246
  sessionId,
24757
25247
  cwd: request.cwd,
24758
- sessionParent,
25248
+ sessionParent: liveSessionParent(),
24759
25249
  home: request.home
24760
25250
  });
24761
25251
  sessionOpened = true;
@@ -24777,7 +25267,7 @@ function createAcpRoleTurnHost(config) {
24777
25267
  currentSessionId: () => sessionId,
24778
25268
  async runRound({ prompt, abortSignal }) {
24779
25269
  const { $schema: _headlessStamp, ...deliveredSchema } = prepared.jsonSchema;
24780
- await recordTurnDelivery(request.runDirectory, {
25270
+ await recordTurnDelivery(await syncTurnRequestLivePlacement(request), {
24781
25271
  systemPrompt: systemPromptOverride,
24782
25272
  outputSchema: deliveredSchema
24783
25273
  }, "acp-host");
@@ -24836,8 +25326,7 @@ function createAcpRoleTurnHost(config) {
24836
25326
  const native = connection?.result?.();
24837
25327
  reportedFailure = native?.knownFailure;
24838
25328
  outcome = native ?? { code: null, stderr: connection?.stderr?.() ?? "", timedOut: false };
24839
- await retainPackageFault({
24840
- runDirectory: request.runDirectory,
25329
+ await retainPackageFaultBesideLivePlacement(request, {
24841
25330
  diagnostic: `ACP turn exception beside native host facts: ${describeErrorIdentity(error)}`,
24842
25331
  error
24843
25332
  });
@@ -24852,8 +25341,7 @@ function createAcpRoleTurnHost(config) {
24852
25341
  try {
24853
25342
  connection.notify("session/cancel", { sessionId });
24854
25343
  } catch (error) {
24855
- await retainPackageFault({
24856
- runDirectory: request.runDirectory,
25344
+ await retainPackageFaultBesideLivePlacement(request, {
24857
25345
  diagnostic: `session cancel failed beside host terminal: ${describeErrorIdentity(error)}`,
24858
25346
  error
24859
25347
  });
@@ -24862,8 +25350,7 @@ function createAcpRoleTurnHost(config) {
24862
25350
  try {
24863
25351
  naturalTermination = await connection.close();
24864
25352
  } catch (error) {
24865
- await retainPackageFault({
24866
- runDirectory: request.runDirectory,
25353
+ await retainPackageFaultBesideLivePlacement(request, {
24867
25354
  diagnostic: `connection close failed beside host terminal: ${describeErrorIdentity(error)}`,
24868
25355
  error
24869
25356
  });
@@ -24875,31 +25362,39 @@ function createAcpRoleTurnHost(config) {
24875
25362
  const nativeFailed = native.code !== null && native.code !== 0 || naturalTermination !== void 0 && (native.timedOut || native.signal !== void 0);
24876
25363
  let knownFailure = outcome.knownFailure;
24877
25364
  if (nativeFailed && knownFailure !== void 0 && knownFailure !== reportedFailure) {
24878
- if (knownFailure !== packageFailure) await retainPackageFault({
24879
- runDirectory: request.runDirectory,
24880
- diagnostic: knownFailure.diagnostic ?? "ACP package failure beside late native termination",
24881
- error: knownFailure
24882
- });
25365
+ if (knownFailure !== packageFailure) {
25366
+ await retainPackageFaultBesideLivePlacement(request, {
25367
+ diagnostic: knownFailure.diagnostic ?? "ACP package failure beside late native termination",
25368
+ error: knownFailure
25369
+ });
25370
+ }
24883
25371
  knownFailure = reportedFailure;
24884
25372
  }
24885
25373
  const { knownFailure: _nativeFailure, ...facts } = native;
24886
25374
  outcome = { ...facts, ...knownFailure === void 0 ? {} : { knownFailure } };
24887
25375
  }
24888
25376
  if (config.hostName !== "hermes" && sessionOpened && sessionId !== void 0) {
24889
- try {
24890
- copyAndRecordHostDossier({
24891
- host: config.hostName,
24892
- sessionId,
24893
- cwd: request.cwd,
24894
- sessionDirectory: sessionDirectoryOf(request.runDirectory),
24895
- sessionParent,
24896
- ...request.home !== void 0 ? { home: request.home } : {}
24897
- });
24898
- } catch (error) {
24899
- await retainPackageFault({
24900
- runDirectory: request.runDirectory,
24901
- diagnostic: `host dossier copy failed beside host terminal: ${describeErrorIdentity(error)}`,
24902
- error
25377
+ const live = await trySyncTurnRequestLivePlacement(request);
25378
+ if ("runDirectory" in live) {
25379
+ try {
25380
+ copyAndRecordHostDossier({
25381
+ host: config.hostName,
25382
+ sessionId,
25383
+ cwd: request.cwd,
25384
+ sessionDirectory: sessionDirectoryOf(live.runDirectory),
25385
+ sessionParent: sessionFileOf(live.runDirectory),
25386
+ ...request.home !== void 0 ? { home: request.home } : {}
25387
+ });
25388
+ } catch (error) {
25389
+ await retainPackageFaultBesideLivePlacement(request, {
25390
+ diagnostic: `host dossier copy failed beside host terminal: ${describeErrorIdentity(error)}`,
25391
+ error
25392
+ });
25393
+ }
25394
+ } else {
25395
+ await retainPackageFaultBesideLivePlacement(request, {
25396
+ diagnostic: `host dossier copy skipped: live run path resolve failed beside host terminal: ${describeErrorIdentity(live.resolveError)}`,
25397
+ error: live.resolveError
24903
25398
  });
24904
25399
  }
24905
25400
  }