@akagilnc/pi-workflow-roles 0.1.4889 → 0.1.4911

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.
@@ -876,7 +876,7 @@ export function resumeTurnRequestProjectionOptions(admitted, request, env, summo
876
876
  };
877
877
  }
878
878
  /** Shared new-turn and in-call auto-resume projection. Seat code supplies prompt and activation. */
879
- export function roleTurnOptions(env, admitted, continuation, extra) {
879
+ export function roleTurnOptions(env, admitted, continuation) {
880
880
  const correlationId = admitted.correlationId ?? env.correlationId;
881
881
  return {
882
882
  packageRoot: env.packageRoot,
@@ -889,7 +889,6 @@ export function roleTurnOptions(env, admitted, continuation, extra) {
889
889
  ? {}
890
890
  : { correlationId }),
891
891
  continuation,
892
- ...(extra?.cwd === undefined ? {} : { cwd: extra.cwd }),
893
892
  ...(env.stationChild === undefined ? {} : { stationChild: env.stationChild }),
894
893
  };
895
894
  }
@@ -982,9 +981,7 @@ export async function runPostAdmissionSeatResume(input) {
982
981
  }
983
982
  adapters = prepared.adapters;
984
983
  }
985
- // Call-local execution env; afterAdmittedPrepare may replace it (Reviewer fresh-copy).
986
- let env = input.env;
987
- let preparedCleanup;
984
+ const env = input.env;
988
985
  const buildRequestAfterLease = async () => {
989
986
  let openCourtAttemptId;
990
987
  // Settlement identity stays on the outer admitted.
@@ -1049,14 +1046,7 @@ export async function runPostAdmissionSeatResume(input) {
1049
1046
  // auto-resume both pass through to the host CLI without a package writer-lease
1050
1047
  // pre-gate (#987 / ADR 0080). Station-child same-ticket/same-parent resume is
1051
1048
  // still call-local auto-resume (#840 / #416).
1052
- // afterAdmittedPrepare runs inside this try so mint failure and cleanup share one finally.
1053
1049
  try {
1054
- if (input.afterAdmittedPrepare !== undefined) {
1055
- const prepared = await input.afterAdmittedPrepare(loaded.admitted);
1056
- if (prepared.env !== undefined)
1057
- env = prepared.env;
1058
- preparedCleanup = prepared.cleanup;
1059
- }
1060
1050
  if (env.stationChild === true) {
1061
1051
  let firstTurn;
1062
1052
  const stationAdapters = withOnceSuccessfulBeforeDispatch(adapters);
@@ -1133,18 +1123,13 @@ export async function runPostAdmissionSeatResume(input) {
1133
1123
  });
1134
1124
  }
1135
1125
  catch (error) {
1136
- // Seat preparation may still surface structural rejection.
1126
+ // Turn construction may still surface structural rejection.
1137
1127
  if (error instanceof CliUsageError) {
1138
1128
  presentStructuralRejection(error, input.io);
1139
1129
  return { exitCode: 2 };
1140
1130
  }
1141
1131
  throw error;
1142
1132
  }
1143
- finally {
1144
- if (preparedCleanup !== undefined) {
1145
- await preparedCleanup();
1146
- }
1147
- }
1148
1133
  }
1149
1134
  /**
1150
1135
  * Shared post-admission one-shot path: folds into runPostAdmissionResumable (#840 / #416).
@@ -3,7 +3,7 @@ import { resolvePackagedMethodSkillPath, } from "../package-resources/method-ski
3
3
  import { packagedRoleActivationFlags, packagedRoleMetadata, } from "../packaged-role-registry.js";
4
4
  import { parentRunPathFromGatePointerInstruction } from "./run-lifecycle.js";
5
5
  export function projectRoleTurnRequest(admitted, roleDetails, options) {
6
- const cwd = options.cwd ?? admitted.projectRoot ?? admitted.repoRoot ?? admitted.cwd;
6
+ const cwd = admitted.projectRoot ?? admitted.repoRoot ?? admitted.cwd;
7
7
  if (cwd === undefined)
8
8
  throw new Error("admitted invocation missing working directory");
9
9
  if (admitted.principal === undefined)
@@ -1,8 +1,7 @@
1
1
  import { execFile } from "node:child_process";
2
2
  import { existsSync } from "node:fs";
3
- import { mkdir, mkdtemp, realpath, rm } from "node:fs/promises";
4
- import { tmpdir } from "node:os";
5
- import { join, relative, sep } from "node:path";
3
+ import { realpath } from "node:fs/promises";
4
+ import { join } from "node:path";
6
5
  import { promisify } from "node:util";
7
6
  import { pickEngineAxis } from "./package-resources/engine-material.js";
8
7
  const AK_ROLE_PACKAGE_ROOT_ENV = "AK_ROLE_PACKAGE_ROOT";
@@ -207,8 +206,7 @@ async function summonPublicRole(options) {
207
206
  ...options.boundTicketNumber === void 0 ? {} : { boundTicketNumber: options.boundTicketNumber },
208
207
  ...options.parentRunPath === void 0 || options.parentRunPath.trim() === "" ? {} : { parentRunPath: options.parentRunPath },
209
208
  ...options.correlationId === void 0 || options.correlationId.trim() === "" ? {} : { correlationId: options.correlationId },
210
- ...options.createRunId === void 0 ? {} : { createRunId: options.createRunId },
211
- ...options.executionCwd === void 0 ? {} : { executionCwd: options.executionCwd }
209
+ ...options.createRunId === void 0 ? {} : { createRunId: options.createRunId }
212
210
  }
213
211
  };
214
212
  } catch (error) {
@@ -288,106 +286,13 @@ function withReviewerLens(argv, lens) {
288
286
  if (separator === -1) return [...argv, "--lens", lens];
289
287
  return [...argv.slice(0, separator), "--lens", lens, ...argv.slice(separator)];
290
288
  }
291
- async function resolveReviewerWorktreeRoots(projectRoot) {
289
+ async function resolveReviewerGitToplevel(projectRoot) {
292
290
  const callerProjectRoot = await realpath(projectRoot);
293
- const sourceProjectRoot = await realpath((await execFileAsync(
291
+ return await realpath((await execFileAsync(
294
292
  "git",
295
293
  ["rev-parse", "--show-toplevel"],
296
294
  { cwd: callerProjectRoot }
297
295
  )).stdout.trim());
298
- const callerRelative = relative(sourceProjectRoot, callerProjectRoot);
299
- const projectRelative = callerRelative === "" || callerRelative === "." || callerRelative.startsWith(`..${sep}`) || callerRelative === ".." ? "" : callerRelative;
300
- return { callerProjectRoot, sourceProjectRoot, projectRelative };
301
- }
302
- function reviewerSandboxPath(worktreeAxis, projectRelative) {
303
- return projectRelative === "" ? worktreeAxis : join(worktreeAxis, projectRelative);
304
- }
305
- async function openEphemeralReviewerWorktree(options) {
306
- const { sourceProjectRoot, projectRelative } = await resolveReviewerWorktreeRoots(
307
- options.projectRoot
308
- );
309
- const { stdout: headStdout } = await execFileAsync(
310
- "git",
311
- ["rev-parse", "--verify", "HEAD^{commit}"],
312
- { cwd: sourceProjectRoot }
313
- );
314
- const targetCommit = headStdout.trim();
315
- const root = await mkdtemp(join(tmpdir(), "ak-reviewer-sandbox-"));
316
- const worktreeRoot = join(root, "work");
317
- let registered = false;
318
- const rollback = async (cause) => {
319
- const cleanupErrors = [];
320
- if (registered) {
321
- try {
322
- await execFileAsync("git", ["worktree", "remove", "--force", worktreeRoot], {
323
- cwd: sourceProjectRoot
324
- });
325
- } catch (error) {
326
- cleanupErrors.push(error);
327
- }
328
- }
329
- try {
330
- await rm(root, { recursive: true, force: true });
331
- } catch (error) {
332
- cleanupErrors.push(error);
333
- }
334
- if (cleanupErrors.length > 0) {
335
- options.onCleanupDiagnostic?.([
336
- "reviewer worktree cleanup failed",
337
- ...cleanupErrors.map((error) => error instanceof Error ? error.message : String(error))
338
- ].join("\n"));
339
- }
340
- throw cause;
341
- };
342
- try {
343
- await execFileAsync("git", ["worktree", "add", "--detach", worktreeRoot, targetCommit], {
344
- cwd: sourceProjectRoot
345
- });
346
- registered = true;
347
- if (projectRelative !== "") {
348
- await mkdir(reviewerSandboxPath(worktreeRoot, projectRelative), { recursive: true });
349
- }
350
- } catch (error) {
351
- await rollback(error);
352
- }
353
- let closed = false;
354
- return {
355
- executionCwd: reviewerSandboxPath(worktreeRoot, projectRelative),
356
- close: async () => {
357
- if (closed) return;
358
- closed = true;
359
- const cleanupErrors = [];
360
- try {
361
- await execFileAsync("git", ["worktree", "remove", worktreeRoot], {
362
- cwd: sourceProjectRoot
363
- });
364
- } catch (error) {
365
- cleanupErrors.push(error);
366
- }
367
- try {
368
- await rm(root, { recursive: true, force: true });
369
- } catch (error) {
370
- cleanupErrors.push(error);
371
- }
372
- if (cleanupErrors.length > 0) {
373
- options.onCleanupDiagnostic?.([
374
- "reviewer worktree cleanup failed",
375
- ...cleanupErrors.map((error) => error instanceof Error ? error.message : String(error))
376
- ].join("\n"));
377
- }
378
- }
379
- };
380
- }
381
- async function withEphemeralReviewerWorktree(options) {
382
- const sandbox = await openEphemeralReviewerWorktree({
383
- projectRoot: options.projectRoot,
384
- ...options.onCleanupDiagnostic === void 0 ? {} : { onCleanupDiagnostic: options.onCleanupDiagnostic }
385
- });
386
- try {
387
- return await options.run(sandbox.executionCwd);
388
- } finally {
389
- await sandbox.close();
390
- }
391
296
  }
392
297
  async function summonParallelReviewerLenses(options) {
393
298
  const describeFailure = (error) => {
@@ -405,7 +310,6 @@ async function summonParallelReviewerLenses(options) {
405
310
  return { completeness: failure, correctness: failure };
406
311
  };
407
312
  let sourceProjectRoot;
408
- let projectRelative;
409
313
  let targetCommit;
410
314
  const statusArgs = [
411
315
  "status",
@@ -416,9 +320,7 @@ async function summonParallelReviewerLenses(options) {
416
320
  ":(top,exclude).claude/worktrees/**"
417
321
  ];
418
322
  try {
419
- const roots = await resolveReviewerWorktreeRoots(options.projectRoot);
420
- sourceProjectRoot = roots.sourceProjectRoot;
421
- projectRelative = roots.projectRelative;
323
+ sourceProjectRoot = await resolveReviewerGitToplevel(options.projectRoot);
422
324
  const { stdout: statusStdout } = await execFileAsync("git", statusArgs, {
423
325
  cwd: sourceProjectRoot
424
326
  });
@@ -444,65 +346,37 @@ async function summonParallelReviewerLenses(options) {
444
346
  } catch (error) {
445
347
  return dualFailure(error);
446
348
  }
447
- const root = await mkdtemp(join(tmpdir(), "ak-reviewer-lenses-"));
448
- const completenessRoot = join(root, "completeness");
449
- const correctnessRoot = join(root, "correctness");
450
- const worktrees = [completenessRoot, correctnessRoot];
451
- const created = /* @__PURE__ */ new Set();
452
- let results;
453
- const creation = await Promise.allSettled(
454
- worktrees.map(async (path) => {
455
- await execFileAsync("git", ["worktree", "add", "--detach", path, targetCommit], {
456
- cwd: sourceProjectRoot
457
- });
458
- created.add(path);
459
- if (projectRelative !== "") {
460
- await mkdir(reviewerSandboxPath(path, projectRelative), { recursive: true });
461
- }
462
- })
463
- );
464
- const creationFailures = creation.flatMap((result) => result.status === "rejected" ? [result.reason] : []);
465
- if (creationFailures.length > 0) {
466
- const failure = failedResult(new AggregateError(
467
- creationFailures,
468
- "parallel reviewer worktree creation failed"
469
- ));
470
- results = { completeness: failure, correctness: failure };
471
- } else {
472
- const summon = (lens, worktreeAxis) => {
473
- const sandbox = reviewerSandboxPath(worktreeAxis, projectRelative);
474
- return summonPublicRole({
475
- role: "reviewer",
476
- argv: withReviewerLens(options.argv, lens),
477
- cwd: options.cwd,
478
- executionCwd: sandbox,
479
- // Ordinary single-axis public semantics — not a nested court station.
480
- stationChild: false,
481
- home: options.home,
482
- ...options.agentDir === void 0 ? {} : { agentDir: options.agentDir },
483
- ...options.credentials === void 0 ? {} : { credentials: options.credentials },
484
- ...options.model === void 0 ? {} : { model: options.model },
485
- ...options.host === void 0 ? {} : { host: options.host },
486
- ...options.engine === void 0 ? {} : { engine: options.engine },
487
- ...options.engineModel === void 0 ? {} : { engineModel: options.engineModel },
488
- ...options.signal === void 0 ? {} : { signal: options.signal },
489
- ...options.correlationId === void 0 ? {} : { correlationId: options.correlationId },
490
- ...options.packageRoot === void 0 ? {} : { packageRoot: options.packageRoot },
491
- ...options.roleTurnHost === void 0 ? {} : { roleTurnHost: options.roleTurnHost },
492
- ...options.hostAdapters === void 0 ? {} : { hostAdapters: options.hostAdapters },
493
- ...options.principalAuthority === void 0 ? {} : { principalAuthority: options.principalAuthority },
494
- ...options.timeoutMs === void 0 ? {} : { timeoutMs: options.timeoutMs }
495
- });
496
- };
497
- const settled = await Promise.allSettled([
498
- summon("completeness", completenessRoot),
499
- summon("correctness", correctnessRoot)
500
- ]);
501
- results = {
502
- completeness: settled[0].status === "fulfilled" ? settled[0].value : failedResult(settled[0].reason),
503
- correctness: settled[1].status === "fulfilled" ? settled[1].value : failedResult(settled[1].reason)
504
- };
505
- }
349
+ const summon = (lens) => {
350
+ return summonPublicRole({
351
+ role: "reviewer",
352
+ argv: withReviewerLens(options.argv, lens),
353
+ cwd: options.cwd,
354
+ // Ordinary single-axis public semantics — not a nested court station.
355
+ stationChild: false,
356
+ home: options.home,
357
+ ...options.agentDir === void 0 ? {} : { agentDir: options.agentDir },
358
+ ...options.credentials === void 0 ? {} : { credentials: options.credentials },
359
+ ...options.model === void 0 ? {} : { model: options.model },
360
+ ...options.host === void 0 ? {} : { host: options.host },
361
+ ...options.engine === void 0 ? {} : { engine: options.engine },
362
+ ...options.engineModel === void 0 ? {} : { engineModel: options.engineModel },
363
+ ...options.signal === void 0 ? {} : { signal: options.signal },
364
+ ...options.correlationId === void 0 ? {} : { correlationId: options.correlationId },
365
+ ...options.packageRoot === void 0 ? {} : { packageRoot: options.packageRoot },
366
+ ...options.roleTurnHost === void 0 ? {} : { roleTurnHost: options.roleTurnHost },
367
+ ...options.hostAdapters === void 0 ? {} : { hostAdapters: options.hostAdapters },
368
+ ...options.principalAuthority === void 0 ? {} : { principalAuthority: options.principalAuthority },
369
+ ...options.timeoutMs === void 0 ? {} : { timeoutMs: options.timeoutMs }
370
+ });
371
+ };
372
+ const settled = await Promise.allSettled([
373
+ summon("completeness"),
374
+ summon("correctness")
375
+ ]);
376
+ let results = {
377
+ completeness: settled[0].status === "fulfilled" ? settled[0].value : failedResult(settled[0].reason),
378
+ correctness: settled[1].status === "fulfilled" ? settled[1].value : failedResult(settled[1].reason)
379
+ };
506
380
  let sealDiagnostic;
507
381
  try {
508
382
  const { stdout: headBeforeStdout } = await execFileAsync(
@@ -547,30 +421,6 @@ ${describeFailure(error)}`;
547
421
  correctness: withSealFailure(results.correctness)
548
422
  };
549
423
  }
550
- const cleanup = await Promise.allSettled(
551
- [...created].map((path) => execFileAsync("git", ["worktree", "remove", path], { cwd: sourceProjectRoot }))
552
- );
553
- const cleanupFailures = cleanup.flatMap((result) => result.status === "rejected" ? [result.reason] : []);
554
- if (cleanupFailures.length === 0) {
555
- const rootCleanup = await Promise.allSettled([rm(root, { recursive: true, force: true })]);
556
- cleanupFailures.push(...rootCleanup.flatMap((result) => result.status === "rejected" ? [result.reason] : []));
557
- }
558
- if (cleanupFailures.length > 0) {
559
- const diagnostic = [
560
- "parallel reviewer worktree cleanup failed",
561
- ...cleanupFailures.map((failure) => failure instanceof Error ? failure.message : String(failure))
562
- ].join("\n");
563
- const withCleanupDiagnostic = (result) => ({
564
- ...result,
565
- stderr: [result.stderr, diagnostic].filter(
566
- (text) => typeof text === "string" && text !== ""
567
- ).join("\n")
568
- });
569
- results = {
570
- completeness: withCleanupDiagnostic(results.completeness),
571
- correctness: withCleanupDiagnostic(results.correctness)
572
- };
573
- }
574
424
  return results;
575
425
  }
576
426
  async function summonGateOfficer(options) {
@@ -646,10 +496,8 @@ async function summonGateOfficer(options) {
646
496
  }
647
497
  export {
648
498
  AK_ROLE_PACKAGE_ROOT_ENV,
649
- openEphemeralReviewerWorktree,
650
499
  resolveSummonsPackageRoot,
651
500
  summonGateOfficer,
652
501
  summonParallelReviewerLenses,
653
- summonPublicRole,
654
- withEphemeralReviewerWorktree
502
+ summonPublicRole
655
503
  };
@@ -155,8 +155,11 @@ async function rewriteOfficerPointerFile(path, rewrites) {
155
155
  // Only the typed direct-officer pointer shape — never arbitrary .pointer.json.
156
156
  if (page.kind !== "direct-officer-run-pointer")
157
157
  return;
158
+ const before = JSON.stringify(page);
158
159
  rewriteRunDirectoryPathFieldsAgainstRewrites(page, OFFICER_POINTER_FIELDS, rewrites);
159
- await writeFile(path, `${JSON.stringify(page)}\n`, "utf8");
160
+ if (JSON.stringify(page) !== before) {
161
+ await writeFile(path, `${JSON.stringify(page)}\n`, "utf8");
162
+ }
160
163
  }
161
164
  async function rewriteSitianRecordsJsonl(path, rewrites) {
162
165
  if (!existsSync(path))
@@ -320,18 +323,25 @@ export async function rewriteRoleRunDurablePages(input) {
320
323
  const admittedPath = join(pagesDirectory, "admitted-request.json");
321
324
  if (existsSync(admittedPath)) {
322
325
  const page = JSON.parse(await readFile(admittedPath, "utf8"));
326
+ const before = JSON.stringify(page);
323
327
  rewriteAdmittedRoleRunPage(page, rewrites);
324
- await writeFile(admittedPath, `${JSON.stringify(page, null, 2)}\n`, "utf8");
328
+ if (JSON.stringify(page) !== before) {
329
+ await writeFile(admittedPath, `${JSON.stringify(page, null, 2)}\n`, "utf8");
330
+ }
325
331
  }
326
332
  const invocationPath = join(pagesDirectory, "invocation.json");
327
333
  if (existsSync(invocationPath)) {
328
334
  const page = JSON.parse(await readFile(invocationPath, "utf8"));
335
+ const before = JSON.stringify(page);
329
336
  rewriteRunDirectoryPathFieldsAgainstRewrites(page, INVOCATION_PAGE_FIELDS, rewrites);
330
- await writeFile(invocationPath, `${JSON.stringify(page, null, 2)}\n`, "utf8");
337
+ if (JSON.stringify(page) !== before) {
338
+ await writeFile(invocationPath, `${JSON.stringify(page, null, 2)}\n`, "utf8");
339
+ }
331
340
  }
332
341
  const statePath = join(pagesDirectory, "run-state.json");
333
342
  if (existsSync(statePath)) {
334
343
  const page = JSON.parse(await readFile(statePath, "utf8"));
344
+ const before = JSON.stringify(page);
335
345
  rewriteRunDirectoryPathFieldsAgainstRewrites(page, RUN_STATE_PAGE_FIELDS, rewrites);
336
346
  if (isPlainObject(page.principal)) {
337
347
  rewriteRunDirectoryPathFieldsAgainstRewrites(page.principal, ["sessionDirectory", "sessionFile"], rewrites);
@@ -340,7 +350,9 @@ export async function rewriteRoleRunDurablePages(input) {
340
350
  if (isPlainObject(page.currentCourt)) {
341
351
  rewriteSummonsMaterials(page.currentCourt.summons, rewrites);
342
352
  }
343
- await writeFile(statePath, `${JSON.stringify(page, null, 2)}\n`, "utf8");
353
+ if (JSON.stringify(page) !== before) {
354
+ await writeFile(statePath, `${JSON.stringify(page, null, 2)}\n`, "utf8");
355
+ }
344
356
  }
345
357
  await rewriteNestedMachinePathPages(pagesDirectory, rewrites);
346
358
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akagilnc/pi-workflow-roles",
3
- "version": "0.1.4889",
3
+ "version": "0.1.4911",
4
4
  "description": "Soul-bound workflow roles for Pi",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -17,7 +17,6 @@ import {
17
17
  resolveMigratingRunTicket,
18
18
  } from "./book-topology-migration-placement.ts";
19
19
  import {
20
- assertBookTopologyMigrationPrerequisites,
21
20
  reconcileMigrationPartition,
22
21
  type BookTopologyMigrationContext,
23
22
  type BookTopologyPartitionMigrator,
@@ -378,13 +377,11 @@ export async function relocateBoardBoundUnboundRunsInBook(
378
377
 
379
378
  /**
380
379
  * Walk every book under `booksDirectory` and relocate board-bound unbound
381
- * runs in place. Requires zero live writer locks (same gate as topology migrate).
380
+ * runs in place without the whole-books topology migration's in-flight gate.
382
381
  */
383
382
  export async function relocateBoardBoundUnboundRunsInBooks(
384
383
  booksDirectory: string,
385
- env: NodeJS.ProcessEnv = process.env,
386
384
  ): Promise<readonly BoardBoundUnboundRelocation[]> {
387
- await assertBookTopologyMigrationPrerequisites(booksDirectory, env);
388
385
  const relocated: BoardBoundUnboundRelocation[] = [];
389
386
  for (const bookKey of await listMigrationBookKeys(booksDirectory)) {
390
387
  const batch = await relocateBoardBoundUnboundRunsInBook(
@@ -192,8 +192,6 @@ export const PUBLIC_ROLE_RECORDS = [
192
192
  settleMethod: "ak-cross-m-review",
193
193
  /** Omitted public lens starts two ordinary single-axis runs (ADR 0052). */
194
194
  parallelLenses: true,
195
- /** Every turn runs in a fresh worktree; durable projectRoot stays the caller project (#946). */
196
- freshExecutionCopy: true,
197
195
  phases: [null],
198
196
  bareCommand: false,
199
197
  outputTool: REVIEWER_OUTPUT_TOOL_NAME,
@@ -132,15 +132,6 @@ function initialPrompt(
132
132
  );
133
133
  }
134
134
 
135
- function hostTurnCwd(env: InstructionSeatRunEnv): { readonly cwd: string } | undefined {
136
- return env.executionCwd === undefined ? undefined : { cwd: env.executionCwd };
137
- }
138
-
139
- function wantsFreshExecutionCopy(role: PackagedRole): boolean {
140
- const record = roleRecord(role);
141
- return "freshExecutionCopy" in record && record.freshExecutionCopy === true;
142
- }
143
-
144
135
  function infraFailure(role: PackagedRole) {
145
136
  const resolveRunnerKnownFailure = seatKnownFailureResolver(role);
146
137
  return resolveRunnerKnownFailure === undefined ? {} : { resolveRunnerKnownFailure };
@@ -260,7 +251,6 @@ async function dispatchAdmitted(
260
251
  const adapters = seatAdapters(admitted, env, material);
261
252
  const execute = async (activeEnv: InstructionSeatRunEnv): Promise<SeatRunResult> => {
262
253
  const auto = "inCallAutoResume" in record && record.inCallAutoResume === true;
263
- const cwd = hostTurnCwd(activeEnv);
264
254
  if (auto) {
265
255
  return await runPostAdmissionResumable({
266
256
  admitted,
@@ -268,7 +258,7 @@ async function dispatchAdmitted(
268
258
  io,
269
259
  buildInitialRequest: () => buildInstructionSeatTurnRequest(
270
260
  admitted,
271
- roleTurnOptions(activeEnv, admitted, { kind: "initial", prompt: initialPrompt(admitted, activeEnv) }, cwd),
261
+ roleTurnOptions(activeEnv, admitted, { kind: "initial", prompt: initialPrompt(admitted, activeEnv) }),
272
262
  ),
273
263
  buildResumeRequest: () => buildInstructionSeatTurnRequest(
274
264
  admitted,
@@ -278,7 +268,7 @@ async function dispatchAdmitted(
278
268
  packageRoot: activeEnv.packageRoot,
279
269
  ...pickEngineAxis(activeEnv),
280
270
  }),
281
- }, cwd),
271
+ }),
282
272
  ),
283
273
  adapters,
284
274
  ...(activeEnv.engine === undefined ? {} : { effectiveEngine: activeEnv.engine }),
@@ -290,31 +280,13 @@ async function dispatchAdmitted(
290
280
  io,
291
281
  request: buildInstructionSeatTurnRequest(
292
282
  admitted,
293
- roleTurnOptions(activeEnv, admitted, { kind: "initial", prompt: initialPrompt(admitted, activeEnv) }, cwd),
283
+ roleTurnOptions(activeEnv, admitted, { kind: "initial", prompt: initialPrompt(admitted, activeEnv) }),
294
284
  ),
295
285
  adapters,
296
286
  ...(activeEnv.engine === undefined ? {} : { effectiveEngine: activeEnv.engine }),
297
287
  });
298
288
  };
299
- if (!wantsFreshExecutionCopy(admitted.role)) return execute(env);
300
- try {
301
- if (env.executionCwd !== undefined) return await execute(env);
302
- const { withEphemeralReviewerWorktree } = await import("../public-role-summons.ts");
303
- return await withEphemeralReviewerWorktree({
304
- projectRoot: admitted.projectRoot,
305
- onCleanupDiagnostic: (diagnostic) => {
306
- io.stderr(`${diagnostic}\n`);
307
- },
308
- run: (executionCwd) => execute({ ...env, executionCwd }),
309
- });
310
- } catch (error) {
311
- return await presentControlledFailure(admitted, {
312
- timedOut: false,
313
- code: null,
314
- stderr: "",
315
- thrown: error,
316
- }, adapters, env.principalAuthority, io) as SeatRunResult;
317
- }
289
+ return execute(env);
318
290
  }
319
291
 
320
292
  /**
@@ -809,9 +781,6 @@ export async function runPublicInstructionSeatResume(
809
781
  env: InstructionSeatRunEnv,
810
782
  io: CliIo,
811
783
  ): Promise<SeatRunResult> {
812
- const execution: { cwd?: string } = {
813
- ...(env.executionCwd === undefined ? {} : { cwd: env.executionCwd }),
814
- };
815
784
  return runPostAdmissionSeatResume<AdmittedRoleInvocation>({
816
785
  request,
817
786
  env,
@@ -835,13 +804,11 @@ export async function runPublicInstructionSeatResume(
835
804
  return loaded;
836
805
  },
837
806
  buildTurnRequest: async (admitted, effective) => {
838
- const activeEnv = execution.cwd === undefined ? env : { ...env, executionCwd: execution.cwd };
839
807
  const summonsPrepared = await prepareSummonsResumeMaterials(admitted.runDirectory, effective.summons);
840
808
  return buildInstructionSeatTurnRequest(
841
809
  admitted,
842
810
  {
843
- ...resumeTurnRequestProjectionOptions(admitted, effective, activeEnv, summonsPrepared),
844
- ...(execution.cwd === undefined ? {} : { cwd: execution.cwd }),
811
+ ...resumeTurnRequestProjectionOptions(admitted, effective, env, summonsPrepared),
845
812
  },
846
813
  );
847
814
  },
@@ -864,24 +831,6 @@ export async function runPublicInstructionSeatResume(
864
831
  ...(knownCause === undefined ? {} : { knownCause }),
865
832
  });
866
833
  },
867
- afterAdmittedPrepare: async (admitted) => {
868
- if (!wantsFreshExecutionCopy(admitted.role)) return {};
869
- if (execution.cwd !== undefined) {
870
- return { env: { ...env, executionCwd: execution.cwd } };
871
- }
872
- const { openEphemeralReviewerWorktree } = await import("../public-role-summons.ts");
873
- const opened = await openEphemeralReviewerWorktree({
874
- projectRoot: admitted.projectRoot,
875
- onCleanupDiagnostic: (diagnostic) => {
876
- io.stderr(`${diagnostic}\n`);
877
- },
878
- });
879
- execution.cwd = opened.executionCwd;
880
- return {
881
- env: { ...env, executionCwd: opened.executionCwd },
882
- cleanup: opened.close,
883
- };
884
- },
885
834
  ...(env.engine === undefined ? {} : { effectiveEngine: env.engine }),
886
835
  });
887
836
  }
@@ -330,12 +330,6 @@ export type PostAdmissionEnv = {
330
330
  boundTicketNumber?: number;
331
331
  /** Station child role run (#840): omit automatic navigator attendance. */
332
332
  stationChild?: boolean;
333
- /**
334
- * Ephemeral host-turn cwd for Reviewer fresh-copy execution (#946 统一新副本).
335
- * Admission and durable projectRoot stay on the caller project; the host turn
336
- * (initial and resume) runs in this sandbox when present.
337
- */
338
- executionCwd?: string;
339
333
  };
340
334
 
341
335
  /**
@@ -1390,7 +1384,6 @@ export function roleTurnOptions(
1390
1384
  env: PostAdmissionEnv,
1391
1385
  admitted: { readonly correlationId?: string },
1392
1386
  continuation: RoleTurnRequest["continuation"],
1393
- extra?: { readonly cwd?: string },
1394
1387
  ): RoleTurnRequestProjectionOptions {
1395
1388
  const correlationId = admitted.correlationId ?? env.correlationId;
1396
1389
  return {
@@ -1404,7 +1397,6 @@ export function roleTurnOptions(
1404
1397
  ? {}
1405
1398
  : { correlationId }),
1406
1399
  continuation,
1407
- ...(extra?.cwd === undefined ? {} : { cwd: extra.cwd }),
1408
1400
  ...(env.stationChild === undefined ? {} : { stationChild: env.stationChild }),
1409
1401
  };
1410
1402
  }
@@ -1514,16 +1506,6 @@ export async function runPostAdmissionSeatResume<
1514
1506
  afterAdmittedLoad?: (
1515
1507
  admitted: A,
1516
1508
  ) => Promise<AfterAdmittedLoadResult<A, T>>;
1517
- /**
1518
- * After the single pre-lease load (and optional afterAdmittedLoad), prepare
1519
- * call-local execution context. Reviewer fresh-copy (#946) mints an ephemeral
1520
- * worktree from the admitted projectRoot here — reuses this load, does not
1521
- * pre-load outside the coordinator. cleanup runs after dispatch settles.
1522
- */
1523
- afterAdmittedPrepare?: (admitted: A) => Promise<{
1524
- readonly env?: PostAdmissionEnv;
1525
- readonly cleanup?: () => Promise<void>;
1526
- }>;
1527
1509
  effectiveEngine?: string;
1528
1510
  }): Promise<{ exitCode: number; admitted?: A; terminal?: T }> {
1529
1511
  let request = input.request;
@@ -1556,9 +1538,7 @@ export async function runPostAdmissionSeatResume<
1556
1538
  adapters = prepared.adapters;
1557
1539
  }
1558
1540
 
1559
- // Call-local execution env; afterAdmittedPrepare may replace it (Reviewer fresh-copy).
1560
- let env = input.env;
1561
- let preparedCleanup: (() => Promise<void>) | undefined;
1541
+ const env = input.env;
1562
1542
 
1563
1543
  const buildRequestAfterLease = async (): Promise<RoleTurnRequest> => {
1564
1544
  let openCourtAttemptId: string | undefined;
@@ -1645,13 +1625,7 @@ export async function runPostAdmissionSeatResume<
1645
1625
  // auto-resume both pass through to the host CLI without a package writer-lease
1646
1626
  // pre-gate (#987 / ADR 0080). Station-child same-ticket/same-parent resume is
1647
1627
  // still call-local auto-resume (#840 / #416).
1648
- // afterAdmittedPrepare runs inside this try so mint failure and cleanup share one finally.
1649
1628
  try {
1650
- if (input.afterAdmittedPrepare !== undefined) {
1651
- const prepared = await input.afterAdmittedPrepare(loaded.admitted);
1652
- if (prepared.env !== undefined) env = prepared.env;
1653
- preparedCleanup = prepared.cleanup;
1654
- }
1655
1629
  if (env.stationChild === true) {
1656
1630
  let firstTurn: RoleTurnRequest | undefined;
1657
1631
  const stationAdapters = withOnceSuccessfulBeforeDispatch(adapters);
@@ -1741,16 +1715,12 @@ export async function runPostAdmissionSeatResume<
1741
1715
  buildRequestAfterLease,
1742
1716
  });
1743
1717
  } catch (error) {
1744
- // Seat preparation may still surface structural rejection.
1718
+ // Turn construction may still surface structural rejection.
1745
1719
  if (error instanceof CliUsageError) {
1746
1720
  presentStructuralRejection(error, input.io);
1747
1721
  return { exitCode: 2 };
1748
1722
  }
1749
1723
  throw error;
1750
- } finally {
1751
- if (preparedCleanup !== undefined) {
1752
- await preparedCleanup();
1753
- }
1754
1724
  }
1755
1725
  }
1756
1726