@akagilnc/pi-workflow-roles 0.1.4905 → 0.1.4913
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.
- package/dist/acp-host/production-host.js +70 -286
- package/dist/headless-host/production-host.js +65 -281
- package/dist/migrate-book-topology.js +0 -2
- package/dist/packaged-role-registry.js +0 -2
- package/dist/public-cli/instruction-seat-run.js +5 -58
- package/dist/public-cli/main.js +56 -272
- package/dist/public-cli/post-admission.js +3 -18
- package/dist/public-cli/turn-request.js +1 -1
- package/dist/public-role-summons.js +38 -190
- package/package.json +1 -1
- package/souls/judge.md +1 -1
- package/src/packaged-role-registry.ts +0 -2
- package/src/public-cli/instruction-seat-run.ts +5 -56
- package/src/public-cli/post-admission.ts +2 -32
- package/src/public-cli/turn-request.ts +1 -7
- package/src/public-role-summons.ts +58 -268
|
@@ -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
|
|
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
|
-
|
|
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
|
-
//
|
|
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 =
|
|
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 {
|
|
4
|
-
import {
|
|
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
|
|
289
|
+
async function resolveReviewerGitToplevel(projectRoot) {
|
|
292
290
|
const callerProjectRoot = await realpath(projectRoot);
|
|
293
|
-
|
|
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
|
-
|
|
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
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
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
|
};
|
package/package.json
CHANGED
package/souls/judge.md
CHANGED
|
@@ -13,7 +13,7 @@ Judge Soul(大理寺)
|
|
|
13
13
|
区分原缺陷所需改动、修复自身造成的返工、无依据的新机制;后两类主导时优先拆除或简化。同缝反复、根因不明、范围发散、疑跨接缝或 flake,先做最小化、证据驱动的诊断,不继续猜修。一轮轮只加不减,本身就是须上报的问题。
|
|
14
14
|
判词
|
|
15
15
|
|
|
16
|
-
* converged
|
|
16
|
+
* converged——署:适用举证责任下的事项均已明确处置,且有本轮御史台无 p2 及以上 finding 为辅证,严重度由你裁定,已驳回的不计。唯一例外:本轮修内司的改动只结清 p2 及以下的类、且没有带进新机制或新行为的,你亲验该改动后可不待御史台而署,判词须写明援引此例外及你验了什么。修理触及 p1、或该改动超出所修的类,仍以本轮御史台为前提。
|
|
17
17
|
* continue——封驳:仍有授权内可纠正的问题,给出需修理的问题类别与法源,具体发现可作为案例/证据,不作施工白名单;授权范围内同类问题一并处置,超出授权的取舍上呈。一次扫净所有类别。
|
|
18
18
|
* escalate——上呈:缺少法源、法源冲突、取舍超出授权,或依据失败走势与证据已无法安全裁定;写明争点与选项。
|
|
19
19
|
|
|
@@ -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) }
|
|
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
|
-
}
|
|
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) }
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
-
//
|
|
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
|
|
|
@@ -47,12 +47,6 @@ export type RoleTurnRequestProjectionOptions = {
|
|
|
47
47
|
invocationScopeId?: string;
|
|
48
48
|
/** Station child role run (#840): omit automatic navigator attendance. */
|
|
49
49
|
stationChild?: boolean;
|
|
50
|
-
/**
|
|
51
|
-
* Optional host-turn cwd override. Durable admitted projectRoot stays the
|
|
52
|
-
* identity source; Reviewer fresh-copy sandboxes (explicit --lens, dual-lens
|
|
53
|
-
* legs, resume) inject the ephemeral worktree here (#946 统一新副本).
|
|
54
|
-
*/
|
|
55
|
-
cwd?: string;
|
|
56
50
|
};
|
|
57
51
|
|
|
58
52
|
export type AdmittedTurnInvocation = {
|
|
@@ -73,7 +67,7 @@ export function projectRoleTurnRequest(
|
|
|
73
67
|
},
|
|
74
68
|
options: RoleTurnRequestProjectionOptions,
|
|
75
69
|
): RoleTurnRequest {
|
|
76
|
-
const cwd =
|
|
70
|
+
const cwd = admitted.projectRoot ?? admitted.repoRoot ?? admitted.cwd;
|
|
77
71
|
if (cwd === undefined) throw new Error("admitted invocation missing working directory");
|
|
78
72
|
if (admitted.principal === undefined) throw new Error("admitted invocation missing principal");
|
|
79
73
|
// #617 DK-3: turn model is the live seat/env model only — never the admitted
|