@akagilnc/pi-workflow-roles 0.1.4782 → 0.1.4802

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/README.md +1 -1
  2. package/README.zh-CN.md +1 -1
  3. package/dist/acp-host/production-host.js +104 -215
  4. package/dist/headless-host/production-host.js +149 -229
  5. package/dist/migrate-book-topology.js +1 -1
  6. package/dist/pi/role-turn-host.js +1 -1
  7. package/dist/public-cli/auto-resume.js +9 -15
  8. package/dist/public-cli/countersign-run.js +75 -87
  9. package/dist/public-cli/diarist-run.js +6 -26
  10. package/dist/public-cli/inspector-run.js +1 -1
  11. package/dist/public-cli/main.js +64 -177
  12. package/dist/public-cli/notary-run.js +0 -3
  13. package/dist/public-cli/option-definitions.js +1 -1
  14. package/dist/public-cli/post-admission.js +35 -65
  15. package/dist/public-cli/reviewer-run.js +1 -1
  16. package/dist/public-cli/run-lifecycle.js +14 -46
  17. package/dist/public-cli/seat-ticket-binding.js +11 -25
  18. package/dist/public-role-summons.js +2 -0
  19. package/package.json +1 -1
  20. package/souls/coder.md +1 -2
  21. package/src/headless-host/role-turn-host.ts +49 -12
  22. package/src/pi/role-turn-host.ts +1 -1
  23. package/src/public-cli/auto-resume.ts +19 -18
  24. package/src/public-cli/countersign-run.ts +76 -129
  25. package/src/public-cli/diarist-run.ts +6 -33
  26. package/src/public-cli/inspector-run.ts +1 -1
  27. package/src/public-cli/invocation.ts +5 -0
  28. package/src/public-cli/notary-run.ts +3 -7
  29. package/src/public-cli/option-definitions.ts +1 -1
  30. package/src/public-cli/post-admission.ts +37 -69
  31. package/src/public-cli/reviewer-run.ts +1 -1
  32. package/src/public-cli/run-lifecycle.ts +18 -66
  33. package/src/public-cli/seat-ticket-binding.ts +12 -28
  34. package/src/public-role-summons.ts +15 -6
  35. package/src/role-runtime.ts +9 -0
@@ -62,7 +62,7 @@ async function spawnEngineDetourOnce(input) {
62
62
  }
63
63
  const command = input.argv[0];
64
64
  const args = input.argv.slice(1);
65
- return await new Promise((resolve21, reject) => {
65
+ return await new Promise((resolve22, reject) => {
66
66
  let settled = false;
67
67
  const signal = input.signal;
68
68
  const child = spawn(command, args, {
@@ -92,7 +92,7 @@ async function spawnEngineDetourOnce(input) {
92
92
  if (signal !== void 0) {
93
93
  signal.removeEventListener("abort", onAbort);
94
94
  }
95
- resolve21(result);
95
+ resolve22(result);
96
96
  };
97
97
  const onAbort = () => {
98
98
  fail4(signal !== void 0 ? abortReasonError(signal) : new Error("aborted"));
@@ -3515,7 +3515,7 @@ function piUserDialogueBody(request) {
3515
3515
  const _exhaustive = request.continuation;
3516
3516
  return _exhaustive;
3517
3517
  })();
3518
- return request.continuation.kind === "resume" && request.activation.role === "reviewer" ? rawPrompt : applyPiNativeSkillInvocation(request.methods, rawPrompt);
3518
+ return request.continuation.kind === "resume" ? rawPrompt : applyPiNativeSkillInvocation(request.methods, rawPrompt);
3519
3519
  }
3520
3520
  async function resolveSelectedPi(command, cwd, env) {
3521
3521
  const searchPath = env.PATH ?? (platform === "win32" ? process.env.PATH ?? "" : "/usr/bin:/bin");
@@ -4883,7 +4883,7 @@ function normalizeReviewComment(raw) {
4883
4883
  function createGhApiRunner(options = {}) {
4884
4884
  const spawnImpl = options.spawnImpl ?? spawn3;
4885
4885
  return async (args, runOptions = {}) => {
4886
- return await new Promise((resolve21, reject) => {
4886
+ return await new Promise((resolve22, reject) => {
4887
4887
  const signal = runOptions.signal;
4888
4888
  if (signal?.aborted) {
4889
4889
  reject(signal.reason ?? new Error("aborted"));
@@ -4956,11 +4956,11 @@ function createGhApiRunner(options = {}) {
4956
4956
  const value = line2.slice(idx + 1).trim();
4957
4957
  headers[name] = value;
4958
4958
  }
4959
- resolve21({ status, headers, bodyText });
4959
+ resolve22({ status, headers, bodyText });
4960
4960
  return;
4961
4961
  }
4962
4962
  if (code === 0) {
4963
- resolve21({ status: 200, headers: {}, bodyText: stdout });
4963
+ resolve22({ status: 200, headers: {}, bodyText: stdout });
4964
4964
  return;
4965
4965
  }
4966
4966
  const failure2 = new Error(
@@ -5559,7 +5559,6 @@ __export(run_lifecycle_exports, {
5559
5559
  acquireRunWriterLease: () => acquireRunWriterLease,
5560
5560
  autopsyWriterLock: () => autopsyWriterLock,
5561
5561
  buildAutoResumeContinuationPrompt: () => buildAutoResumeContinuationPrompt,
5562
- buildResumeContinuationPrompt: () => buildResumeContinuationPrompt,
5563
5562
  clearCurrentCourt: () => clearCurrentCourt,
5564
5563
  clearTypedProviderHttpObservation: () => clearTypedProviderHttpObservation,
5565
5564
  describeErrorIdentity: () => describeErrorIdentity,
@@ -5596,32 +5595,18 @@ __export(run_lifecycle_exports, {
5596
5595
  recordCurrentCourt: () => recordCurrentCourt,
5597
5596
  recordTypedProviderHttpStatus: () => recordTypedProviderHttpStatus,
5598
5597
  renderResumeCommand: () => renderResumeCommand,
5599
- selectResumeContinuationPrompt: () => selectResumeContinuationPrompt,
5600
5598
  writeRoleRunState: () => writeRoleRunState
5601
5599
  });
5602
5600
  import { chmod, lstat as lstat2, open, readdir as readdir4, readFile as readFile9, unlink as unlink2, writeFile as writeFile3 } from "node:fs/promises";
5603
5601
  import { basename as basename5, join as join16 } from "node:path";
5604
- function selectResumeContinuationPrompt(message, engineMaterial) {
5605
- const lines = message !== void 0 ? [message] : [];
5606
- return appendEngineSessionMaterial(lines, engineMaterial).join("\n");
5607
- }
5608
- function buildResumeContinuationPrompt(options) {
5609
- return selectResumeContinuationPrompt(
5610
- options.message,
5611
- engineSessionMaterialFromOptions({
5612
- packageRoot: options.packageRoot,
5613
- ...pickEngineAxis(options)
5614
- })
5615
- );
5616
- }
5617
5602
  function buildAutoResumeContinuationPrompt(options) {
5618
- return selectResumeContinuationPrompt(
5619
- RESUME_TRANSPORT_ENVELOPE,
5603
+ return appendEngineSessionMaterial(
5604
+ [RESUME_TRANSPORT_ENVELOPE],
5620
5605
  engineSessionMaterialFromOptions({
5621
5606
  packageRoot: options.packageRoot,
5622
5607
  ...pickEngineAxis(options)
5623
5608
  })
5624
- );
5609
+ ).join("\n");
5625
5610
  }
5626
5611
  function isV1ResumableProvider(provider) {
5627
5612
  return V1_RESUMABLE_PROVIDERS.includes(provider);
@@ -6166,7 +6151,7 @@ async function runHasFormedSessionPrincipal(runDirectory) {
6166
6151
  }
6167
6152
  }
6168
6153
  async function findLatestRunIdForSeatTicket(input) {
6169
- if (input.ticketNumber === void 0 && input.parentRunPath === void 0) {
6154
+ if (input.parentRunPath.trim() === "") {
6170
6155
  return void 0;
6171
6156
  }
6172
6157
  const ledgerHome = resolveActivationLedgerHome(input.home);
@@ -6185,13 +6170,8 @@ async function findLatestRunIdForSeatTicket(input) {
6185
6170
  if (!entry.endsWith(suffix)) continue;
6186
6171
  const runId = entry.slice(0, entry.length - suffix.length);
6187
6172
  if (runId.length === 0) continue;
6188
- if (input.parentRunPath !== void 0) {
6189
- const parentPath = await readRunParentPath(runDirectory);
6190
- if (parentPath !== input.parentRunPath) continue;
6191
- } else if (input.ticketNumber !== void 0) {
6192
- const ticketNumber = await readBoardTicketNumber(runDirectory);
6193
- if (ticketNumber !== input.ticketNumber) continue;
6194
- }
6173
+ const parentPath = await readRunParentPath(runDirectory);
6174
+ if (parentPath !== input.parentRunPath) continue;
6195
6175
  if (!await runHasFormedSessionPrincipal(runDirectory)) continue;
6196
6176
  if (best === void 0 || runId > best) best = runId;
6197
6177
  }
@@ -8054,7 +8034,7 @@ var init_option_definitions = __esm({
8054
8034
  },
8055
8035
  resume: {
8056
8036
  command: "resume",
8057
- summary: "Resume a role run under the live seat table (model/host/engine); session principal must still exist. [message] applies only to seats that accept caller instruction; Notary/\u7B26\u5B9D\u90CE must omit message and derives evidence from the existing source-run/dossier binding. Global --model/--thinking/--host/--engine must be placed before <runId> (either before `resume` or between `resume` and <runId>); the one argv after <runId> is the opaque message, not a flag position (#471).",
8037
+ summary: "Resume a role run under the live seat table (model/host/engine); session principal must still exist. Every callable seat, including Notary/\u7B26\u5B9D\u90CE, accepts the optional caller message and passes it through unchanged as the continuation prompt. Notary explicit new still accepts only its source-run locator, not a caller prompt. Global --model/--thinking/--host/--engine must be placed before <runId> (either before `resume` or between `resume` and <runId>); the one argv after <runId> is the opaque message, not a flag position (#471).",
8058
8038
  usage: ["ak-role resume <runId> [message]"],
8059
8039
  examples: [
8060
8040
  "ak-role resume 01abc\u2026",
@@ -12743,12 +12723,12 @@ function createSystemCollectorClock() {
12743
12723
  return {
12744
12724
  wallNow: () => /* @__PURE__ */ new Date(),
12745
12725
  monoNow: () => Number(process.hrtime.bigint() - start) / 1e6,
12746
- sleep: (ms, signal) => new Promise((resolve21, reject) => {
12726
+ sleep: (ms, signal) => new Promise((resolve22, reject) => {
12747
12727
  if (signal?.aborted) {
12748
12728
  reject(signal.reason ?? new Error("aborted"));
12749
12729
  return;
12750
12730
  }
12751
- const timer = setTimeout(resolve21, ms);
12731
+ const timer = setTimeout(resolve22, ms);
12752
12732
  const onAbort = () => {
12753
12733
  clearTimeout(timer);
12754
12734
  reject(signal?.reason ?? new Error("aborted"));
@@ -17036,10 +17016,10 @@ function presentFailureTerminal(terminal, io) {
17036
17016
  }
17037
17017
  function defaultNavigatorGraceSleep() {
17038
17018
  let timer;
17039
- const sleep = ((ms) => new Promise((resolve21) => {
17019
+ const sleep = ((ms) => new Promise((resolve22) => {
17040
17020
  timer = setTimeout(() => {
17041
17021
  timer = void 0;
17042
- resolve21();
17022
+ resolve22();
17043
17023
  }, ms);
17044
17024
  }));
17045
17025
  sleep.cancel = () => {
@@ -17051,7 +17031,7 @@ function defaultNavigatorGraceSleep() {
17051
17031
  return sleep;
17052
17032
  }
17053
17033
  function raceNavigatorGrace(work, graceMs = NAVIGATOR_POST_ROLE_GRACE_MS, sleep = defaultNavigatorGraceSleep()) {
17054
- return new Promise((resolve21, reject) => {
17034
+ return new Promise((resolve22, reject) => {
17055
17035
  let settled = false;
17056
17036
  const finish = (action) => {
17057
17037
  if (settled) return;
@@ -17060,11 +17040,11 @@ function raceNavigatorGrace(work, graceMs = NAVIGATOR_POST_ROLE_GRACE_MS, sleep
17060
17040
  action();
17061
17041
  };
17062
17042
  void work.then(
17063
- (value) => finish(() => resolve21({ status: "done", value })),
17043
+ (value) => finish(() => resolve22({ status: "done", value })),
17064
17044
  (error) => finish(() => reject(error))
17065
17045
  );
17066
17046
  void sleep(graceMs).then(() => {
17067
- finish(() => resolve21({ status: "timeout" }));
17047
+ finish(() => resolve22({ status: "timeout" }));
17068
17048
  });
17069
17049
  });
17070
17050
  }
@@ -17135,15 +17115,12 @@ var init_settlement = __esm({
17135
17115
  // src/public-cli/seat-ticket-binding.ts
17136
17116
  async function tryResumeSameTicketSeatRun(input) {
17137
17117
  if (input.freshSummons === true) return void 0;
17138
- if (input.parentRunPath === void 0 && input.ticketNumber === void 0) {
17139
- return void 0;
17140
- }
17118
+ if (input.parentRunPath.trim() === "") return void 0;
17141
17119
  const previousRunId = await findLatestRunIdForSeatTicket({
17142
17120
  home: input.home,
17143
17121
  bookKey: resolveBookKeyFromGit(input.projectRoot),
17144
17122
  role: input.role,
17145
- ...input.parentRunPath === void 0 ? {} : { parentRunPath: input.parentRunPath },
17146
- ...input.ticketNumber === void 0 ? {} : { ticketNumber: input.ticketNumber }
17123
+ parentRunPath: input.parentRunPath
17147
17124
  });
17148
17125
  if (previousRunId === void 0) return void 0;
17149
17126
  return await input.resume(previousRunId, input.summons);
@@ -18290,22 +18267,10 @@ async function runWithAutoResumeLoop(options) {
18290
18267
  let everyAttemptThrew = true;
18291
18268
  const retainedErrorFiles = [];
18292
18269
  while (true) {
18293
- let lease;
18294
- try {
18295
- lease = await acquireRunWriterLease(
18296
- options.admitted.runDirectory,
18297
- (diagnostic) => options.io.stderr(diagnostic)
18298
- );
18299
- } catch (error) {
18300
- if (error instanceof RunWriterLeaseHeldError) {
18301
- presentStructuralRejection(error, options.io);
18302
- return { exitCode: 2 };
18303
- }
18304
- throw error;
18305
- }
18306
18270
  let result;
18307
18271
  let turnStartedBeforeThrow = false;
18308
18272
  try {
18273
+ const lease = isFirst ? await acquireRunWriterLease(options.admitted.runDirectory) : void 0;
18309
18274
  result = await options.dispatch(currentPayload, lease, isFirst, dummyIo);
18310
18275
  } catch (error) {
18311
18276
  lastThrownError = error;
@@ -18439,8 +18404,8 @@ async function runWithAutoResumeLoop(options) {
18439
18404
  autoResumeAttempts++;
18440
18405
  if (result?.turnDispatched === true || turnStartedBeforeThrow) {
18441
18406
  currentPayload = options.buildResumePayload();
18407
+ isFirst = false;
18442
18408
  }
18443
- isFirst = false;
18444
18409
  }
18445
18410
  }
18446
18411
  var dummyIo, TurnDispatchedFailure, DISPATCH_ERROR_RETENTION_ENTRY_TYPE;
@@ -18930,7 +18895,7 @@ async function dispatchPostAdmissionTurn(input) {
18930
18895
  await recordBestEffortPostDispatchDiagnostic(
18931
18896
  admitted,
18932
18897
  env,
18933
- `current-court cleanup failed after accepted settlement (best-effort continue, self-heals on next resume): ${describeErrorIdentity(error)}`,
18898
+ `current-court cleanup failed after accepted settlement (best-effort continue): ${describeErrorIdentity(error)}`,
18934
18899
  io
18935
18900
  );
18936
18901
  }
@@ -19106,21 +19071,14 @@ function resumeTurnRequestProjectionOptions(admitted, request, env, summonsPrepa
19106
19071
  } else if (request.summons !== void 0) {
19107
19072
  prompt = request.message;
19108
19073
  } else {
19109
- prompt = buildResumeContinuationPrompt({
19110
- packageRoot: env.packageRoot,
19111
- ...pickEngineAxis(env),
19112
- message: request.message
19113
- });
19074
+ prompt = request.message;
19114
19075
  }
19115
19076
  } else if (summonsPrepared !== void 0) {
19116
19077
  prompt = officerDialogue ? summonsPrepared.instructionEmpty ? "" : summonsPrepared.instruction : buildInstructionTransportPrompt(summonsPrepared);
19117
19078
  } else if (request.summons !== void 0) {
19118
19079
  prompt = "";
19119
19080
  } else {
19120
- prompt = buildResumeContinuationPrompt({
19121
- packageRoot: env.packageRoot,
19122
- ...pickEngineAxis(env)
19123
- });
19081
+ prompt = "";
19124
19082
  }
19125
19083
  return {
19126
19084
  packageRoot: env.packageRoot,
@@ -19145,7 +19103,7 @@ async function dispatchAfterWriterLease(input) {
19145
19103
  handedOffToDispatch = true;
19146
19104
  return await input.dispatch(request);
19147
19105
  } finally {
19148
- if (!handedOffToDispatch) {
19106
+ if (!handedOffToDispatch && input.lease !== void 0) {
19149
19107
  await input.lease.release();
19150
19108
  }
19151
19109
  }
@@ -19198,20 +19156,11 @@ async function runPostAdmissionSeatResume(input) {
19198
19156
  let preparedCleanup;
19199
19157
  const buildRequestAfterLease = async () => {
19200
19158
  let openCourtAttemptId;
19201
- let admittedForBuild = loaded.admitted;
19159
+ const admittedForBuild = loaded.admitted;
19202
19160
  if (request.summons === void 0) {
19203
19161
  const openCourt = await readCurrentCourt(admittedForBuild.runDirectory);
19204
19162
  if (openCourt !== void 0) {
19205
19163
  openCourtAttemptId = openCourt.courtAttemptId;
19206
- request = {
19207
- runId: request.runId,
19208
- ...request.message === void 0 ? {} : { message: request.message },
19209
- ...openCourt.summons === void 0 ? {} : { summons: openCourt.summons }
19210
- };
19211
- if (openCourt.summons !== void 0) {
19212
- const reloaded = await input.load(request);
19213
- admittedForBuild = reloaded.admitted;
19214
- }
19215
19164
  }
19216
19165
  }
19217
19166
  if (request.summons !== void 0) {
@@ -19273,7 +19222,7 @@ async function runPostAdmissionSeatResume(input) {
19273
19222
  // Same as public manual resume: prior-court sealed acceptance is not a
19274
19223
  // redispatch brake (#833). New-court station-child turns still auto-resume.
19275
19224
  dispatch: async (payload, lease, _isFirst, attemptIo) => dispatchAfterWriterLease({
19276
- lease,
19225
+ ...lease === void 0 ? {} : { lease },
19277
19226
  build: async () => {
19278
19227
  if (payload.resumeTurn && firstTurn !== void 0) {
19279
19228
  return {
@@ -19297,7 +19246,7 @@ async function runPostAdmissionSeatResume(input) {
19297
19246
  env,
19298
19247
  io: attemptIo,
19299
19248
  request: turnRequest,
19300
- lease,
19249
+ ...lease === void 0 ? {} : { lease },
19301
19250
  adapters: stationAdapters,
19302
19251
  persistRunState: false,
19303
19252
  ...input.effectiveEngine === void 0 ? {} : { effectiveEngine: input.effectiveEngine }
@@ -19383,7 +19332,7 @@ async function runPostAdmissionResumable(input) {
19383
19332
  },
19384
19333
  io: attemptIo,
19385
19334
  request,
19386
- lease,
19335
+ ...lease === void 0 ? {} : { lease },
19387
19336
  adapters,
19388
19337
  persistRunState: false,
19389
19338
  // #600: every attempt (initial + auto-resume) writes seat engine when present.
@@ -19625,11 +19574,6 @@ async function runPublicNotaryResume(request, env, io) {
19625
19574
  env,
19626
19575
  io,
19627
19576
  load: async (effective) => {
19628
- if (effective.message !== void 0) {
19629
- throw new CliUsageError(
19630
- "notary rejects caller prompt/instruction; only zero caller-prompt continuation admitted"
19631
- );
19632
- }
19633
19577
  const loaded = await loadResumableNotaryRun(
19634
19578
  env.home,
19635
19579
  effective.runId,
@@ -20383,29 +20327,7 @@ async function runPublicDiarist(argv, env, io, parseDiaristArgv2) {
20383
20327
  }
20384
20328
  throw error;
20385
20329
  }
20386
- const projectRoot = parsed.project ?? env.cwd;
20387
20330
  const handoffTicket = env.boundTicketNumber;
20388
- if (typeof handoffTicket === "number" && Number.isSafeInteger(handoffTicket) && handoffTicket >= 1) {
20389
- const summons = {
20390
- instruction: parsed.instruction,
20391
- instructionEmpty: parsed.instruction.trim() === "",
20392
- attachmentPaths: parsed.attachmentPaths
20393
- };
20394
- const resumed = await tryResumeSameTicketSeatRun({
20395
- home: env.home,
20396
- projectRoot,
20397
- role: "diarist",
20398
- ticketNumber: handoffTicket,
20399
- freshSummons: env.freshSummons,
20400
- summons,
20401
- resume: (runId, materials) => runPublicDiaristResume(
20402
- { runId, ...materials === void 0 ? {} : { summons: materials } },
20403
- env,
20404
- io
20405
- )
20406
- });
20407
- if (resumed !== void 0) return resumed;
20408
- }
20409
20331
  let admitted;
20410
20332
  try {
20411
20333
  admitted = await admitDiaristInvocation({
@@ -20490,7 +20412,6 @@ var init_diarist_run = __esm({
20490
20412
  init_invocation();
20491
20413
  init_post_admission();
20492
20414
  init_run_lifecycle();
20493
- init_seat_ticket_binding();
20494
20415
  init_settlement();
20495
20416
  init_turn_request();
20496
20417
  init_run_ticket_number();
@@ -20506,6 +20427,7 @@ __export(countersign_run_exports, {
20506
20427
  runPublicCountersign: () => runPublicCountersign,
20507
20428
  runPublicCountersignResume: () => runPublicCountersignResume
20508
20429
  });
20430
+ import { resolve as resolve14 } from "node:path";
20509
20431
  function buildCountersignTurnRequest(admitted, options) {
20510
20432
  return projectRoleTurnRequest(
20511
20433
  admitted,
@@ -20700,6 +20622,28 @@ async function runPublicCountersign(argv, env, io, parseCountersignArgv2) {
20700
20622
  throw error;
20701
20623
  }
20702
20624
  let admitted;
20625
+ const gateParentRunPath = typeof env.parentRunPath === "string" && env.parentRunPath.trim() !== "" ? env.parentRunPath : void 0;
20626
+ if (gateParentRunPath !== void 0) {
20627
+ const resumeInstruction = env.reviewReask ?? env.gateReviewInstruction ?? parsed.instruction;
20628
+ const resumed = await tryResumeSameTicketSeatRun({
20629
+ home: env.home,
20630
+ projectRoot: resolve14(parsed.project ?? env.cwd),
20631
+ role: "countersign",
20632
+ parentRunPath: gateParentRunPath,
20633
+ freshSummons: env.freshSummons,
20634
+ summons: {
20635
+ sourceRunPath: gateParentRunPath,
20636
+ instruction: resumeInstruction,
20637
+ instructionEmpty: resumeInstruction.trim() === ""
20638
+ },
20639
+ resume: (runId, materials) => runPublicCountersignResume(
20640
+ { runId, ...materials === void 0 ? {} : { summons: materials } },
20641
+ env,
20642
+ io
20643
+ )
20644
+ });
20645
+ if (resumed !== void 0) return resumed;
20646
+ }
20703
20647
  try {
20704
20648
  admitted = await admitCountersignInvocation({
20705
20649
  home: env.home,
@@ -20743,7 +20687,7 @@ async function runPublicCountersign(argv, env, io, parseCountersignArgv2) {
20743
20687
  instruction: parsed.instruction,
20744
20688
  projectRoot: admitted.projectRoot,
20745
20689
  failureLabel: "unbound summons",
20746
- // #969: parent durable ticket is the resume/bind key (ADR 0079).
20690
+ // #969: parent durable ticket is the bind key (not a resume lookup).
20747
20691
  ...env.boundTicketNumber === void 0 ? {} : { boundTicketNumber: env.boundTicketNumber }
20748
20692
  },
20749
20693
  env,
@@ -20799,59 +20743,13 @@ async function runPublicCountersign(argv, env, io, parseCountersignArgv2) {
20799
20743
  } else if (isSafePositiveTicketNumber(env.boundTicketNumber)) {
20800
20744
  typedTicket = env.boundTicketNumber;
20801
20745
  }
20802
- if (typedTicket !== void 0) {
20803
- const resumeInstruction = env.reviewReask ?? env.gateReviewInstruction ?? parsed.instruction;
20804
- const summons = {
20805
- instruction: resumeInstruction,
20806
- instructionEmpty: resumeInstruction.trim() === ""
20807
- };
20808
- const resumed = await tryResumeSameTicketSeatRun({
20809
- home: env.home,
20810
- projectRoot: admitted.projectRoot,
20811
- role: "countersign",
20812
- ticketNumber: typedTicket,
20813
- freshSummons: env.freshSummons,
20814
- summons,
20815
- resume: async (runId, materials) => {
20816
- const retained = await loadResumableCountersignRun(
20817
- env.home,
20818
- runId,
20819
- env.principalAuthority
20820
- );
20821
- if (retained.admitted === void 0) {
20822
- throw new Error(
20823
- `retained countersign run disappeared before resume: ${runId}`
20824
- );
20825
- }
20826
- const frozenPaths = (await freezePreparedAttachmentsIntoRun(
20827
- preparedAttachments,
20828
- retained.admitted.runDirectory,
20829
- `s-${Date.now().toString(36)}`
20830
- )).map((attachment) => attachment.frozenPath);
20831
- const preparedMaterials = {
20832
- ...materials ?? {},
20833
- ...frozenPaths.length === 0 ? {} : { attachmentPaths: frozenPaths }
20834
- };
20835
- return await runPublicCountersignResume(
20836
- {
20837
- runId,
20838
- summons: preparedMaterials
20839
- },
20840
- {
20841
- ...env,
20842
- ...typedCourtTicketNumbers === void 0 ? {} : { pendingCourtTicketNumbers: typedCourtTicketNumbers }
20843
- },
20844
- io
20845
- );
20846
- }
20847
- });
20848
- if (resumed !== void 0) {
20849
- return resumed;
20850
- }
20851
- }
20852
20746
  }
20853
20747
  await materializeAdmission();
20854
20748
  await markRunAdmitted(admitted, env.principalAuthority);
20749
+ if (gateParentRunPath !== void 0) {
20750
+ await persistAdmittedSourceRunPath(admitted, gateParentRunPath);
20751
+ admitted = { ...admitted, sourceRunPath: gateParentRunPath };
20752
+ }
20855
20753
  if (identityDiaristRan && typedTicket !== void 0) {
20856
20754
  try {
20857
20755
  await bindAdmittedTicketNumber(admitted, typedTicket);
@@ -20970,22 +20868,7 @@ async function runPublicCountersignResume(request, env, io) {
20970
20868
  )
20971
20869
  );
20972
20870
  },
20973
- adapters: countersignAdapters({
20974
- beforeDispatch: async (admitted) => {
20975
- if (admitted.courtTicketNumbersDamage !== void 0) {
20976
- throw new StationChildExhaustedError(
20977
- admitted.courtTicketNumbersDamage
20978
- );
20979
- }
20980
- if (env.pendingCourtTicketNumbers !== void 0) {
20981
- await bindCourtTicketNumbersOnAdmitted(
20982
- admitted,
20983
- env.pendingCourtTicketNumbers
20984
- );
20985
- }
20986
- await runCountersignCourtDiaristStation(admitted, env, io);
20987
- }
20988
- }),
20871
+ adapters: countersignAdapters(),
20989
20872
  ...env.engine === void 0 ? {} : { effectiveEngine: env.engine }
20990
20873
  });
20991
20874
  }
@@ -21013,7 +20896,7 @@ __export(reviewer_run_exports, {
21013
20896
  runPublicReviewer: () => runPublicReviewer,
21014
20897
  runPublicReviewerResume: () => runPublicReviewerResume
21015
20898
  });
21016
- import { resolve as resolve14 } from "node:path";
20899
+ import { resolve as resolve15 } from "node:path";
21017
20900
  function reviewerMethods(packageRoot) {
21018
20901
  return [{ kind: "skill", path: resolvePackagedMethodSkillPath(packageRoot, "ak-cross-m-review") }];
21019
20902
  }
@@ -21105,7 +20988,7 @@ async function runPublicReviewer(argv, env, io, parseReviewerArgv2) {
21105
20988
  // Do not substitute the resolved project path — relative --project must
21106
20989
  // not be re-resolved against a shifted cwd.
21107
20990
  cwd: env.cwd,
21108
- projectRoot: resolve14(parsed.project ?? env.cwd),
20991
+ projectRoot: resolve15(parsed.project ?? env.cwd),
21109
20992
  // Typed base from the public parse — precheck only; child argv stays verbatim.
21110
20993
  baseRevision: parsed.baseRevision,
21111
20994
  home: env.home,
@@ -21278,7 +21161,7 @@ async function runPublicReviewerResume(request, env, io) {
21278
21161
  ...sandbox.executionCwd === void 0 ? {} : { cwd: sandbox.executionCwd },
21279
21162
  continuation: {
21280
21163
  kind: "resume",
21281
- prompt: reviewerResumePrompt(activeEnv, effective.message)
21164
+ prompt: effective.message ?? ""
21282
21165
  }
21283
21166
  });
21284
21167
  },
@@ -21544,6 +21427,7 @@ async function summonPublicRole(options) {
21544
21427
  ...options.reviewReask === void 0 ? {} : { reviewReask: options.reviewReask },
21545
21428
  ...options.gateReviewInstruction === void 0 ? {} : { gateReviewInstruction: options.gateReviewInstruction },
21546
21429
  ...options.boundTicketNumber === void 0 ? {} : { boundTicketNumber: options.boundTicketNumber },
21430
+ ...options.parentRunPath === void 0 || options.parentRunPath.trim() === "" ? {} : { parentRunPath: options.parentRunPath },
21547
21431
  ...options.correlationId === void 0 || options.correlationId.trim() === "" ? {} : { correlationId: options.correlationId },
21548
21432
  ...options.createRunId === void 0 ? {} : { createRunId: options.createRunId },
21549
21433
  ...options.executionCwd === void 0 ? {} : { executionCwd: options.executionCwd }
@@ -22046,6 +21930,7 @@ async function summonGateOfficer(options) {
22046
21930
  argv: ["--project", options.cwd, "--", instruction],
22047
21931
  ...common,
22048
21932
  correlationId,
21933
+ parentRunPath: options.sourceRunDirectory,
22049
21934
  ...parentTicket === void 0 ? {} : { boundTicketNumber: parentTicket }
22050
21935
  });
22051
21936
  }
@@ -22342,7 +22227,7 @@ import {
22342
22227
  statSync as statSync4,
22343
22228
  writeFileSync as writeFileSync3
22344
22229
  } from "node:fs";
22345
- import { isAbsolute as isAbsolute9, resolve as resolve15 } from "node:path";
22230
+ import { isAbsolute as isAbsolute9, resolve as resolve16 } from "node:path";
22346
22231
  var ActivationSessionFileMissingError = class extends Error {
22347
22232
  code = "AK_ACTIVATION_SESSION_FILE_MISSING";
22348
22233
  path;
@@ -22387,7 +22272,7 @@ function durableSessionPointer(sessionManager) {
22387
22272
  `Workflow role activation requires an absolute durable session file path; got relative path: ${file}`
22388
22273
  );
22389
22274
  }
22390
- const resolvedFile = resolve15(file);
22275
+ const resolvedFile = resolve16(file);
22391
22276
  try {
22392
22277
  lstatSync2(resolvedFile);
22393
22278
  } catch (error) {
@@ -24034,7 +23919,7 @@ import { createHash as createHash9 } from "node:crypto";
24034
23919
  init_navigator_invocation_identity();
24035
23920
  init_packaged_role_registry();
24036
23921
  init_activation_ledger_topology();
24037
- import { resolve as resolve16 } from "node:path";
23922
+ import { resolve as resolve17 } from "node:path";
24038
23923
  import "@earendil-works/pi-coding-agent";
24039
23924
  import { Type as Type22 } from "typebox";
24040
23925
 
@@ -24481,7 +24366,7 @@ function navigatorSubjectKey(subjectRoot, subject, provenance = "role_input") {
24481
24366
  }
24482
24367
  function navigatorSubjectKeyForInput(subjectRoot, reference, cwd = process.cwd()) {
24483
24368
  if (issueRoot(subjectRoot) !== void 0 || !subjectRoot.includes("/.ak/work/")) return subjectRoot;
24484
- const resolvedReference = resolve16(cwd, reference);
24369
+ const resolvedReference = resolve17(cwd, reference);
24485
24370
  const marker = "/runs/";
24486
24371
  if (resolvedReference.includes(marker)) {
24487
24372
  return subjectRoot;
@@ -25199,7 +25084,7 @@ init_submission_errors();
25199
25084
  init_submission_errors();
25200
25085
  import { execFileSync as execFileSync4 } from "node:child_process";
25201
25086
  import { existsSync as existsSync11, lstatSync as lstatSync3, readdirSync as readdirSync3, readFileSync as readFileSync5, rmdirSync, rmSync } from "node:fs";
25202
- import { resolve as resolve17 } from "node:path";
25087
+ import { resolve as resolve18 } from "node:path";
25203
25088
  var WORKER_SUBMISSION_GATE_RECORD_KIND = WORKER_SUBMISSION_GATE_KIND;
25204
25089
  var WORKER_COMMIT_BASELINE_ENTRY_TYPE = "commit-baseline";
25205
25090
  var WORKER_COMMIT_REMINDER_BOUNCE_ENTRY_TYPE = "commit-reminder-bounce";
@@ -25248,7 +25133,7 @@ function escapeGitConfigValueRegex(value) {
25248
25133
  function unsetOwnedHooksPath(file) {
25249
25134
  const owned = [];
25250
25135
  for (const value of tryGetAll(file, "core.hooksPath")) {
25251
- if (!ownedHook(resolve17(value, HOOK_FILE))) continue;
25136
+ if (!ownedHook(resolve18(value, HOOK_FILE))) continue;
25252
25137
  try {
25253
25138
  gitFile(file, [
25254
25139
  "--unset-all",
@@ -25263,15 +25148,15 @@ function unsetOwnedHooksPath(file) {
25263
25148
  return owned;
25264
25149
  }
25265
25150
  function rmOwnedDir(dir) {
25266
- const hookPath = resolve17(dir, HOOK_FILE);
25151
+ const hookPath = resolve18(dir, HOOK_FILE);
25267
25152
  if (!ownedHook(hookPath)) return;
25268
25153
  rmSync(hookPath, { force: true });
25269
25154
  if (existsSync11(dir) && readdirSync3(dir).length === 0) rmdirSync(dir);
25270
25155
  }
25271
25156
  function linkedGitDirs(commonDir) {
25272
- const root = resolve17(commonDir, "worktrees");
25157
+ const root = resolve18(commonDir, "worktrees");
25273
25158
  if (!existsSync11(root)) return [];
25274
- return readdirSync3(root).map((name) => resolve17(root, name)).filter((dir) => lstatSync3(dir).isDirectory());
25159
+ return readdirSync3(root).map((name) => resolve18(root, name)).filter((dir) => lstatSync3(dir).isDirectory());
25275
25160
  }
25276
25161
  function uninstallPackageWorkerHooks(cwd) {
25277
25162
  let inside;
@@ -25285,14 +25170,14 @@ function uninstallPackageWorkerHooks(cwd) {
25285
25170
  const clear = (configFile) => {
25286
25171
  for (const hooks of unsetOwnedHooksPath(configFile)) rmOwnedDir(hooks);
25287
25172
  };
25288
- clear(resolve17(commonDir, "config"));
25289
- clear(resolve17(commonDir, "config.worktree"));
25290
- rmOwnedDir(resolve17(commonDir, HOOKS_DIR));
25291
- const legacy = resolve17(commonDir, "hooks", HOOK_FILE);
25173
+ clear(resolve18(commonDir, "config"));
25174
+ clear(resolve18(commonDir, "config.worktree"));
25175
+ rmOwnedDir(resolve18(commonDir, HOOKS_DIR));
25176
+ const legacy = resolve18(commonDir, "hooks", HOOK_FILE);
25292
25177
  if (ownedHook(legacy)) rmSync(legacy, { force: true });
25293
25178
  for (const gitDir of linkedGitDirs(commonDir)) {
25294
- clear(resolve17(gitDir, "config.worktree"));
25295
- rmOwnedDir(resolve17(gitDir, HOOKS_DIR));
25179
+ clear(resolve18(gitDir, "config.worktree"));
25180
+ rmOwnedDir(resolve18(gitDir, HOOKS_DIR));
25296
25181
  }
25297
25182
  }
25298
25183
  function isRecord15(value) {
@@ -26450,11 +26335,15 @@ function createSecretariatRoleRuntime(roleHost, dependencies, hostActions) {
26450
26335
  const summoned = summon === void 0 ? await (async () => {
26451
26336
  const coordinates = readRoleRunCoordinates(ctx, "secretariat summons");
26452
26337
  const { summonPublicRole: summonPublicRole2 } = await Promise.resolve().then(() => (init_public_role_summons(), public_role_summons_exports));
26338
+ const { readBoardTicketNumber: readBoardTicketNumber2 } = await Promise.resolve().then(() => (init_run_ticket_number(), run_ticket_number_exports));
26339
+ const parentTicket = await readBoardTicketNumber2(coordinates.runDirectory);
26453
26340
  return summonPublicRole2({
26454
26341
  role: "countersign",
26455
26342
  argv: ["--project", coordinates.projectRoot, "--", instruction],
26456
26343
  cwd: coordinates.projectRoot,
26457
26344
  home: coordinates.home,
26345
+ parentRunPath: coordinates.runDirectory,
26346
+ ...parentTicket === void 0 ? {} : { boundTicketNumber: parentTicket },
26458
26347
  ...signal === void 0 ? {} : { signal },
26459
26348
  ...correlationId === void 0 ? {} : { correlationId },
26460
26349
  ...dependencies.packageRoot === void 0 ? {} : { packageRoot: dependencies.packageRoot },
@@ -27459,11 +27348,11 @@ init_role_activation_flags();
27459
27348
  init_submission_correctable_error();
27460
27349
  init_navigator_invocation_identity();
27461
27350
  async function listen(server, path) {
27462
- await new Promise((resolve21, reject) => {
27351
+ await new Promise((resolve22, reject) => {
27463
27352
  server.once("error", reject);
27464
27353
  server.listen(path, () => {
27465
27354
  server.off("error", reject);
27466
- resolve21();
27355
+ resolve22();
27467
27356
  });
27468
27357
  });
27469
27358
  }
@@ -27905,8 +27794,8 @@ async function prepareRoleEnvelope(options) {
27905
27794
  try {
27906
27795
  const closeAll = server.closeAllConnections;
27907
27796
  if (typeof closeAll === "function") closeAll.call(server);
27908
- await new Promise((resolve21, reject) => {
27909
- server.close((error) => error ? reject(error) : resolve21());
27797
+ await new Promise((resolve22, reject) => {
27798
+ server.close((error) => error ? reject(error) : resolve22());
27910
27799
  });
27911
27800
  } catch (error) {
27912
27801
  cleanupFailures.push(error);
@@ -28048,7 +27937,7 @@ import { join as join42 } from "node:path";
28048
27937
  // src/canonical-skill-binding.ts
28049
27938
  import { readFile as readFile21, realpath as realpath8 } from "node:fs/promises";
28050
27939
  import { homedir } from "node:os";
28051
- import { dirname as dirname22, resolve as resolve18 } from "node:path";
27940
+ import { dirname as dirname22, resolve as resolve19 } from "node:path";
28052
27941
  import { stripFrontmatter } from "@earendil-works/pi-coding-agent";
28053
27942
  function captureCanonicalSkillExpansion(name, snapshot, configuredPath, evidence, originalRequest) {
28054
27943
  const matchedPath = evidence?.location === configuredPath ? configuredPath : evidence?.location === snapshot.path ? snapshot.path : void 0;
@@ -28071,7 +27960,7 @@ var CanonicalSkillUnavailableError = class extends Error {
28071
27960
  code = "canonical-skill-unavailable";
28072
27961
  };
28073
27962
  async function loadCanonicalSkillBinding(name) {
28074
- const configuredPath = resolve18(
27963
+ const configuredPath = resolve19(
28075
27964
  homedir(),
28076
27965
  `.agents/skills/${name}/SKILL.md`
28077
27966
  );
@@ -28119,7 +28008,7 @@ init_doctor_evidence();
28119
28008
  init_doctor_evidence();
28120
28009
  init_host_contracts();
28121
28010
  import { readFile as readFile22 } from "node:fs/promises";
28122
- import { resolve as resolve19 } from "node:path";
28011
+ import { resolve as resolve20 } from "node:path";
28123
28012
  init_notary_source_run();
28124
28013
  init_packaged_role_registry();
28125
28014
  init_invocation();
@@ -28127,7 +28016,7 @@ function navigatorInputReference(getFlag, role) {
28127
28016
  if (getFlag === void 0) return void 0;
28128
28017
  const name = packagedRoleInputFlag(role);
28129
28018
  const value = name === void 0 ? void 0 : getFlag(name);
28130
- return typeof value === "string" && value !== "" ? resolve19(value) : void 0;
28019
+ return typeof value === "string" && value !== "" ? resolve20(value) : void 0;
28131
28020
  }
28132
28021
  async function loadNavigatorWorkContext(options) {
28133
28022
  const reference = navigatorInputReference(options.getFlag, options.role);
@@ -28148,7 +28037,7 @@ async function loadNavigatorWorkContext(options) {
28148
28037
  }
28149
28038
  const publicRunDir = runDirectoryFromHostContext(options.context);
28150
28039
  const currentSessionDir = options.context.sessionManager.getSessionDir();
28151
- const isBoundPublicRun = publicRunDir !== void 0 && resolve19(currentSessionDir) === resolve19(publicRunDir, "session");
28040
+ const isBoundPublicRun = publicRunDir !== void 0 && resolve20(currentSessionDir) === resolve20(publicRunDir, "session");
28152
28041
  if (options.role === "judge" && isBoundPublicRun) {
28153
28042
  let admitted;
28154
28043
  try {
@@ -28181,9 +28070,9 @@ async function loadNavigatorWorkContext(options) {
28181
28070
  }
28182
28071
  const workRoot = subjectRoot.includes("/.ak/work/") ? subjectRoot : void 0;
28183
28072
  const authorityFiles = workRoot === void 0 ? [] : [
28184
- resolve19(workRoot, "authority.md"),
28185
- resolve19(workRoot, "authority.txt"),
28186
- resolve19(workRoot, "design-v2/owner-direction.md")
28073
+ resolve20(workRoot, "authority.md"),
28074
+ resolve20(workRoot, "authority.txt"),
28075
+ resolve20(workRoot, "design-v2/owner-direction.md")
28187
28076
  ];
28188
28077
  let authorityMaterial;
28189
28078
  for (const path of authorityFiles) {
@@ -28367,7 +28256,7 @@ function hostAbortedError(message = "host aborted") {
28367
28256
  function raceAgainstHostAbort(work, abortSignal, message = "host aborted") {
28368
28257
  if (abortSignal?.aborted) return Promise.reject(hostAbortedError(message));
28369
28258
  if (abortSignal === void 0) return work;
28370
- return new Promise((resolve21, reject) => {
28259
+ return new Promise((resolve22, reject) => {
28371
28260
  let settled = false;
28372
28261
  const onAbort = () => {
28373
28262
  if (settled) return;
@@ -28382,7 +28271,7 @@ function raceAgainstHostAbort(work, abortSignal, message = "host aborted") {
28382
28271
  if (settled) return;
28383
28272
  settled = true;
28384
28273
  abortSignal.removeEventListener("abort", onAbort);
28385
- resolve21(value);
28274
+ resolve22(value);
28386
28275
  },
28387
28276
  (error) => {
28388
28277
  if (settled) return;
@@ -28634,8 +28523,8 @@ function connectAcpStdio(options) {
28634
28523
  request(method, params) {
28635
28524
  if (closed) return Promise.reject(terminalError ?? acpError("acp-connection-closed", "ACP connection is closed"));
28636
28525
  const id = ++nextId;
28637
- return new Promise((resolve21, reject) => {
28638
- pending.set(id, { resolve: resolve21, reject });
28526
+ return new Promise((resolve22, reject) => {
28527
+ pending.set(id, { resolve: resolve22, reject });
28639
28528
  child.stdin.write(`${JSON.stringify({ jsonrpc: "2.0", id, method, params })}
28640
28529
  `, (error) => {
28641
28530
  if (error === null || error === void 0) return;
@@ -28662,7 +28551,7 @@ function connectAcpStdio(options) {
28662
28551
  settleClosed(acpError("acp-connection-closed", "ACP connection is closed"));
28663
28552
  child.stdin.end();
28664
28553
  child.kill("SIGTERM");
28665
- await new Promise((resolve21) => child.once("close", () => resolve21()));
28554
+ await new Promise((resolve22) => child.once("close", () => resolve22()));
28666
28555
  }
28667
28556
  });
28668
28557
  }
@@ -28883,7 +28772,7 @@ function createAcpRoleTurnHost(config) {
28883
28772
  // src/acp-host/seat-profile-soul.ts
28884
28773
  import { constants as constants2 } from "node:fs";
28885
28774
  import { access as access5, copyFile, lstat as lstat8, mkdir as mkdir7, readlink as readlink2, symlink as symlink2, unlink as unlink4 } from "node:fs/promises";
28886
- import { dirname as dirname24, join as join44, relative as relative4, resolve as resolve20 } from "node:path";
28775
+ import { dirname as dirname24, join as join44, relative as relative4, resolve as resolve21 } from "node:path";
28887
28776
  function seatProfileName(spec, role) {
28888
28777
  return `${spec.namePrefix}${role}`;
28889
28778
  }
@@ -28901,7 +28790,7 @@ async function pathExists2(path) {
28901
28790
  async function ensureSeatProfileSoul(options) {
28902
28791
  const { spec, operatorHome, packageRoot, role } = options;
28903
28792
  const profileName = seatProfileName(spec, role);
28904
- const soulTarget = resolve20(packageRoleSoulPath(packageRoot, role));
28793
+ const soulTarget = resolve21(packageRoleSoulPath(packageRoot, role));
28905
28794
  if (!await pathExists2(soulTarget)) {
28906
28795
  throw new Error(`packaged role soul missing: ${soulTarget}`);
28907
28796
  }