@akagilnc/pi-workflow-roles 0.1.3280 → 0.1.3353

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 (41) hide show
  1. package/README.md +5 -5
  2. package/README.zh-CN.md +5 -5
  3. package/dist/audit-escalation.js +31 -4
  4. package/dist/gatekeeper-role.js +25 -4
  5. package/dist/grok/production-host.js +1167 -862
  6. package/dist/inspector-contracts.js +5 -2
  7. package/dist/notary-contracts.js +16 -5
  8. package/dist/packaged-role-registry.js +0 -7
  9. package/dist/public-cli/main.js +867 -757
  10. package/package.json +1 -1
  11. package/src/audit-escalation.ts +52 -8
  12. package/src/collector-ledger.ts +309 -74
  13. package/src/collector-receipt.ts +0 -1
  14. package/src/collector-role.ts +21 -14
  15. package/src/diarist-mechanical.ts +16 -5
  16. package/src/gatekeeper-role.ts +33 -4
  17. package/src/grok/role-envelope.ts +68 -52
  18. package/src/inspector-contracts.ts +6 -3
  19. package/src/inspector-role.ts +5 -2
  20. package/src/notary-contracts.ts +20 -5
  21. package/src/notary-role.ts +2 -2
  22. package/src/packaged-role-registry.ts +0 -12
  23. package/src/public-cli/cli.ts +50 -125
  24. package/src/public-cli/coder-run.ts +5 -19
  25. package/src/public-cli/collector-run.ts +65 -21
  26. package/src/public-cli/countersign-run.ts +14 -40
  27. package/src/public-cli/doctor-run.ts +50 -6
  28. package/src/public-cli/fixer-run.ts +5 -19
  29. package/src/public-cli/gleaner-left-run.ts +14 -40
  30. package/src/public-cli/inspector-run.ts +51 -7
  31. package/src/public-cli/instruction-seat-run.ts +27 -0
  32. package/src/public-cli/judge-run.ts +11 -36
  33. package/src/public-cli/merger-run.ts +5 -19
  34. package/src/public-cli/notary-run.ts +54 -5
  35. package/src/public-cli/option-definitions.ts +3 -3
  36. package/src/public-cli/post-admission.ts +76 -0
  37. package/src/public-cli/reviewer-run.ts +5 -19
  38. package/src/public-cli/run-lifecycle.ts +342 -107
  39. package/src/public-cli/settlement.ts +134 -71
  40. package/src/role-runtime.ts +18 -1
  41. package/src/submission-ledger.ts +55 -5
@@ -37,6 +37,7 @@ import {
37
37
  import { seatModelOnly } from "./registry.ts";
38
38
  import { CliUsageError } from "./cli-errors.ts";
39
39
  import type { CliIo } from "./cli-io.ts";
40
+ import type { PostAdmissionEnv } from "./post-admission.ts";
40
41
  import type { RoleTurnHost } from "../host-contracts.ts";
41
42
  import { loadProductionGrokHostFactory } from "./load-production-grok-host.ts";
42
43
  import {
@@ -73,15 +74,14 @@ import {
73
74
  type TypedOptionConsumer,
74
75
  } from "./option-definitions.ts";
75
76
  import { runPublicCoder, runPublicCoderResume } from "./coder-run.ts";
76
- import { runPublicInstructionSeat } from "./instruction-seat-run.ts";
77
- import { runPublicCollector } from "./collector-run.ts";
77
+ import { runPublicInstructionSeat, runPublicInstructionSeatResume } from "./instruction-seat-run.ts";
78
+ import { runPublicCollector, runPublicCollectorResume } from "./collector-run.ts";
78
79
  import { runPublicCountersign, runPublicCountersignResume } from "./countersign-run.ts";
79
80
  import { runPublicGleanerLeft, runPublicGleanerLeftResume } from "./gleaner-left-run.ts";
80
- import { ONE_SHOT_ROLES } from "../packaged-role-registry.ts";
81
- import { runPublicDoctor } from "./doctor-run.ts";
81
+ import { runPublicDoctor, runPublicDoctorResume } from "./doctor-run.ts";
82
82
  import { runPublicFixer, runPublicFixerResume } from "./fixer-run.ts";
83
- import { runPublicNotary } from "./notary-run.ts";
84
- import { runPublicInspector } from "./inspector-run.ts";
83
+ import { runPublicNotary, runPublicNotaryResume } from "./notary-run.ts";
84
+ import { runPublicInspector, runPublicInspectorResume } from "./inspector-run.ts";
85
85
  import { runPublicJudge, runPublicResume } from "./judge-run.ts";
86
86
  import { runPublicMerger, runPublicMergerResume } from "./merger-run.ts";
87
87
  import { runPublicReviewer, runPublicReviewerResume } from "./reviewer-run.ts";
@@ -91,6 +91,41 @@ import {
91
91
  peekRoleRunRole,
92
92
  type PublicResumeRequest,
93
93
  } from "./run-lifecycle.ts";
94
+
95
+ /**
96
+ * Single authoritative resume dispatch (#633): durable role → seat + public
97
+ * resume runner. Seat-specific loader validation, turn projection, and
98
+ * adapters live in each seat's resume module.
99
+ */
100
+ const RESUME_SEAT_DISPATCH: Record<
101
+ NonNullable<Awaited<ReturnType<typeof peekRoleRunRole>>>,
102
+ {
103
+ readonly seat: PublicCallableRole;
104
+ readonly run: (
105
+ request: PublicResumeRequest,
106
+ env: PostAdmissionEnv,
107
+ io: CliIo,
108
+ ) => Promise<{
109
+ exitCode: number;
110
+ terminal?: TerminalResult;
111
+ staleWriterLeaseReclaimed?: true;
112
+ }>;
113
+ }
114
+ > = {
115
+ judge: { seat: "judge", run: runPublicResume },
116
+ coder: { seat: "coder", run: runPublicCoderResume },
117
+ fixer: { seat: "fixer", run: runPublicFixerResume },
118
+ reviewer: { seat: "reviewer", run: runPublicReviewerResume },
119
+ merger: { seat: "merger", run: runPublicMergerResume },
120
+ countersign: { seat: "countersign", run: runPublicCountersignResume },
121
+ "gleaner-left": { seat: "gleaner-left", run: runPublicGleanerLeftResume },
122
+ collector: { seat: "collector", run: runPublicCollectorResume },
123
+ doctor: { seat: "doctor", run: runPublicDoctorResume },
124
+ notary: { seat: "notary", run: runPublicNotaryResume },
125
+ inspector: { seat: "inspector", run: runPublicInspectorResume },
126
+ gatekeeper: { seat: "gatekeeper", run: runPublicInstructionSeatResume },
127
+ navigator: { seat: "navigator", run: runPublicInstructionSeatResume },
128
+ };
94
129
  import {
95
130
  INTERNAL_ROLE_ENTRYPOINT_RELATIVE,
96
131
  isPublicCallableRole,
@@ -1148,135 +1183,25 @@ export async function runAkRole(
1148
1183
  env.credentials ?? (await loadCredentialProviders(agentDir));
1149
1184
  const resumeRequest = parseResumeRequest(parsed.args);
1150
1185
  const resumeRole = await peekRoleRunRole(home, resumeRequest.runId);
1151
- // One-shot seats refuse resume — single typed owner, not a per-role chain.
1152
- if (resumeRole !== undefined && ONE_SHOT_ROLES.includes(resumeRole)) {
1153
- throw new CliUsageError(
1154
- `${resumeRole} role runs are one-shot and cannot be resumed`,
1155
- );
1156
- }
1157
- const resumeSeatRole =
1158
- resumeRole === "coder"
1159
- ? "coder"
1160
- : resumeRole === "fixer"
1161
- ? "fixer"
1162
- : resumeRole === "reviewer"
1163
- ? "reviewer"
1164
- : resumeRole === "merger"
1165
- ? "merger"
1166
- : resumeRole === "countersign"
1167
- ? "countersign"
1168
- : resumeRole === "gleaner-left"
1169
- ? "gleaner-left"
1170
- : "judge";
1186
+ // #633: single authoritative resume dispatch — the seat follows the
1187
+ // durable admitted role; missing durable role keeps the judge path.
1188
+ const dispatch =
1189
+ resumeRole === undefined
1190
+ ? RESUME_SEAT_DISPATCH.judge
1191
+ : RESUME_SEAT_DISPATCH[resumeRole];
1171
1192
  // #617 DK-4: resume resolves model/host/engine from the live seat table
1172
1193
  // exactly as a new leg would (flag → persistent → default). Cross-host
1173
1194
  // resume delivers prior native records as context to the target host.
1174
1195
  const seat = resolveEffectiveSeat(
1175
1196
  config,
1176
- resumeSeatRole,
1197
+ dispatch.seat,
1177
1198
  credentials,
1178
1199
  invocationFromParsed(parsed),
1179
1200
  );
1180
- if (resumeRole === "coder") {
1181
- const result = await runPublicCoderResume(
1182
- resumeRequest,
1183
- createRoleEnvironment(env, {
1184
- role: "coder",
1185
- home,
1186
- agentDir,
1187
- cwd,
1188
- credentials,
1189
- seat,
1190
- config,
1191
- }),
1192
- io,
1193
- );
1194
- return cliResultFromRoleRun(result);
1195
- }
1196
- if (resumeRole === "fixer") {
1197
- const result = await runPublicFixerResume(
1198
- resumeRequest,
1199
- createRoleEnvironment(env, {
1200
- role: "fixer",
1201
- home,
1202
- agentDir,
1203
- cwd,
1204
- credentials,
1205
- seat,
1206
- config,
1207
- }),
1208
- io,
1209
- );
1210
- return cliResultFromRoleRun(result);
1211
- }
1212
- if (resumeRole === "reviewer") {
1213
- const result = await runPublicReviewerResume(
1214
- resumeRequest,
1215
- createRoleEnvironment(env, {
1216
- role: "reviewer",
1217
- home,
1218
- agentDir,
1219
- cwd,
1220
- credentials,
1221
- seat,
1222
- config,
1223
- }),
1224
- io,
1225
- );
1226
- return cliResultFromRoleRun(result);
1227
- }
1228
- if (resumeRole === "merger") {
1229
- const result = await runPublicMergerResume(
1230
- resumeRequest,
1231
- createRoleEnvironment(env, {
1232
- role: "merger",
1233
- home,
1234
- agentDir,
1235
- cwd,
1236
- credentials,
1237
- seat,
1238
- config,
1239
- }),
1240
- io,
1241
- );
1242
- return cliResultFromRoleRun(result);
1243
- }
1244
- if (resumeRole === "countersign") {
1245
- const result = await runPublicCountersignResume(
1246
- resumeRequest,
1247
- createRoleEnvironment(env, {
1248
- role: "countersign",
1249
- home,
1250
- agentDir,
1251
- cwd,
1252
- credentials,
1253
- seat,
1254
- config,
1255
- }),
1256
- io,
1257
- );
1258
- return cliResultFromRoleRun(result);
1259
- }
1260
- if (resumeRole === "gleaner-left") {
1261
- const result = await runPublicGleanerLeftResume(
1262
- resumeRequest,
1263
- createRoleEnvironment(env, {
1264
- role: "gleaner-left",
1265
- home,
1266
- agentDir,
1267
- cwd,
1268
- credentials,
1269
- seat,
1270
- config,
1271
- }),
1272
- io,
1273
- );
1274
- return cliResultFromRoleRun(result);
1275
- }
1276
- const result = await runPublicResume(
1201
+ const result = await dispatch.run(
1277
1202
  resumeRequest,
1278
1203
  createRoleEnvironment(env, {
1279
- role: "judge",
1204
+ role: dispatch.seat,
1280
1205
  home,
1281
1206
  agentDir,
1282
1207
  cwd,
@@ -44,6 +44,7 @@ import {
44
44
  runPostAdmissionResumable,
45
45
  type PostAdmissionAdapters,
46
46
  type PostAdmissionEnv,
47
+ resumeTurnRequestProjectionOptions,
47
48
  } from "./post-admission.ts";
48
49
 
49
50
  export type CoderRunEnv = PostAdmissionEnv & {
@@ -256,25 +257,10 @@ export async function runPublicCoderResume(
256
257
  }
257
258
  }
258
259
 
259
- const turnRequest = buildCoderTurnRequest(admitted, {
260
- packageRoot: env.packageRoot,
261
- home: env.home,
262
- agentDir: env.agentDir,
263
- ...(env.model === undefined ? {} : { model: env.model }),
264
- ...(env.engine === undefined ? {} : { engine: env.engine }),
265
- ...(env.timeoutMs === undefined ? {} : { timeoutMs: env.timeoutMs }),
266
- ...(admitted.correlationId === undefined && env.correlationId === undefined
267
- ? {}
268
- : { correlationId: admitted.correlationId ?? env.correlationId }),
269
- continuation: {
270
- kind: "resume",
271
- prompt: buildResumeContinuationPrompt({
272
- packageRoot: env.packageRoot,
273
- ...(env.engine === undefined ? {} : { engine: env.engine }),
274
- ...(request.message === undefined ? {} : { message: request.message }),
275
- }),
276
- },
277
- });
260
+ const turnRequest = buildCoderTurnRequest(
261
+ admitted,
262
+ resumeTurnRequestProjectionOptions(admitted, request, env),
263
+ );
278
264
 
279
265
  return await runPostAdmissionManualResume({
280
266
  admitted,
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Public Collector Role run: admit a structured PR target → explicit Internal activate
3
- * → settle Terminal result (#112 / #517). One-shot; no resume path (Collector rejects
4
- * session resume/fork/reload). Lifecycle is the shared post-admission coordinator.
3
+ * → settle Terminal result (#112 / #517). #633: manual resume continues the exact
4
+ * session. Lifecycle is the shared post-admission coordinator.
5
5
  */
6
6
  import type { DurablePrincipalAuthority, RoleTurnRequest } from "../host-contracts.ts";
7
7
  import { engineSessionMaterialFromOptions } from "../package-resources/engine-material.ts";
@@ -14,9 +14,16 @@ import {
14
14
  } from "./invocation.ts";
15
15
  import {
16
16
  runPostAdmissionOneShot,
17
+ type PostAdmissionAdapters,
17
18
  type PostAdmissionEnv,
19
+ runPostAdmissionSeatResume,
20
+ resumeTurnRequestProjectionOptions,
18
21
  } from "./post-admission.ts";
19
- import { markRunAdmitted } from "./run-lifecycle.ts";
22
+ import {
23
+ loadResumableCollectorRun,
24
+ markRunAdmitted,
25
+ type PublicResumeRequest,
26
+ } from "./run-lifecycle.ts";
20
27
  import {
21
28
  presentStructuralRejection,
22
29
  readCollectorInfrastructureFailure,
@@ -109,25 +116,62 @@ export async function runPublicCollector(
109
116
  env,
110
117
  io,
111
118
  request: turnRequest,
112
- adapters: {
113
- trySettle: (admitted, authority) => trySettleCollectorTerminalResult(admitted, authority),
114
- shouldPresentSettled: () => true,
115
- resolveRunnerKnownFailure: async ({ result, sessionFile }) => {
116
- const infrastructureFailure = await readCollectorInfrastructureFailure(sessionFile);
117
- return (
118
- result.knownFailure ??
119
- (infrastructureFailure === undefined
120
- ? undefined
121
- : {
122
- cause: infrastructureFailure.cause,
123
- diagnostic: infrastructureFailure.diagnostic,
124
- ...(infrastructureFailure.identity === undefined
125
- ? {}
126
- : { identity: infrastructureFailure.identity }),
127
- })
128
- );
129
- },
119
+ adapters: collectorAdapters(),
120
+ ...(env.engine === undefined ? {} : { effectiveEngine: env.engine }),
121
+ });
122
+ }
123
+
124
+ function collectorAdapters(): PostAdmissionAdapters<AdmittedCollectorInvocation> {
125
+ return {
126
+ trySettle: (admitted, authority) => trySettleCollectorTerminalResult(admitted, authority),
127
+ shouldPresentSettled: () => true,
128
+ resolveRunnerKnownFailure: async ({ result, sessionFile }) => {
129
+ const infrastructureFailure = await readCollectorInfrastructureFailure(sessionFile);
130
+ return (
131
+ result.knownFailure ??
132
+ (infrastructureFailure === undefined
133
+ ? undefined
134
+ : {
135
+ cause: infrastructureFailure.cause,
136
+ diagnostic: infrastructureFailure.diagnostic,
137
+ ...(infrastructureFailure.identity === undefined
138
+ ? {}
139
+ : { identity: infrastructureFailure.identity }),
140
+ })
141
+ );
130
142
  },
143
+ };
144
+ }
145
+
146
+ /**
147
+ * Resume a previously admitted Collector run (#633). Repository/PR identity
148
+ * restores from the durable admitted request; the session principal reopens.
149
+ */
150
+ export async function runPublicCollectorResume(
151
+ request: PublicResumeRequest,
152
+ env: CollectorRunEnv,
153
+ io: CliIo,
154
+ ): Promise<{
155
+ exitCode: number;
156
+ admitted?: AdmittedCollectorInvocation;
157
+ terminal?: TerminalResult;
158
+ }> {
159
+ return await runPostAdmissionSeatResume({
160
+ request,
161
+ env,
162
+ io,
163
+ load: () =>
164
+ loadResumableCollectorRun(
165
+ env.home,
166
+ request.runId,
167
+ env.principalAuthority,
168
+ ),
169
+ buildTurnRequest: (admitted) =>
170
+ buildCollectorTurnRequest(
171
+ admitted,
172
+ resumeTurnRequestProjectionOptions(admitted, request, env),
173
+ ),
174
+ adapters: collectorAdapters(),
131
175
  ...(env.engine === undefined ? {} : { effectiveEngine: env.engine }),
132
176
  });
133
177
  }
@@ -33,14 +33,14 @@ import {
33
33
  } from "./invocation.ts";
34
34
  import { tryHomeFromAkRolesPath } from "../activation-ledger-topology.ts";
35
35
  import {
36
- runPostAdmissionManualResume,
37
36
  runPostAdmissionOneShot,
38
37
  type PostAdmissionEnv,
38
+ runPostAdmissionSeatResume,
39
+ resumeTurnRequestProjectionOptions,
39
40
  } from "./post-admission.ts";
40
41
  import {
41
42
  loadResumableCountersignRun,
42
43
  markRunAdmitted,
43
- buildResumeContinuationPrompt,
44
44
  type PublicResumeRequest,
45
45
  } from "./run-lifecycle.ts";
46
46
  import {
@@ -187,47 +187,21 @@ export async function runPublicCountersignResume(
187
187
  admitted?: AdmittedCountersignInvocation;
188
188
  terminal?: TerminalResult;
189
189
  }> {
190
- let loaded;
191
- try {
192
- loaded = await loadResumableCountersignRun(
190
+ return await runPostAdmissionSeatResume({
191
+ request,
192
+ env,
193
+ io,
194
+ load: () =>
195
+ loadResumableCountersignRun(
193
196
  env.home,
194
197
  request.runId,
195
198
  env.principalAuthority,
196
- );
197
- } catch (error) {
198
- if (error instanceof CliUsageError) {
199
- presentStructuralRejection(error, io);
200
- return { exitCode: 2 };
201
- }
202
- throw error;
203
- }
204
-
205
- const { admitted } = loaded;
206
- const turnRequest = buildCountersignTurnRequest(admitted, {
207
- packageRoot: env.packageRoot,
208
- home: env.home,
209
- agentDir: env.agentDir,
210
- ...(env.model === undefined ? {} : { model: env.model }),
211
- ...(env.engine === undefined ? {} : { engine: env.engine }),
212
- ...(env.timeoutMs === undefined ? {} : { timeoutMs: env.timeoutMs }),
213
- ...(admitted.correlationId === undefined && env.correlationId === undefined
214
- ? {}
215
- : { correlationId: admitted.correlationId ?? env.correlationId }),
216
- continuation: {
217
- kind: "resume",
218
- prompt: buildResumeContinuationPrompt({
219
- packageRoot: env.packageRoot,
220
- ...(env.engine === undefined ? {} : { engine: env.engine }),
221
- ...(request.message === undefined ? {} : { message: request.message }),
222
- }),
223
- },
224
- });
225
-
226
- return await runPostAdmissionManualResume({
227
- admitted,
228
- env,
229
- io,
230
- request: turnRequest,
199
+ ),
200
+ buildTurnRequest: (admitted) =>
201
+ buildCountersignTurnRequest(
202
+ admitted,
203
+ resumeTurnRequestProjectionOptions(admitted, request, env),
204
+ ),
231
205
  adapters: countersignAdapters(),
232
206
  ...(env.engine === undefined ? {} : { effectiveEngine: env.engine }),
233
207
  });
@@ -14,9 +14,16 @@ import {
14
14
  } from "./invocation.ts";
15
15
  import {
16
16
  runPostAdmissionOneShot,
17
+ type PostAdmissionAdapters,
17
18
  type PostAdmissionEnv,
19
+ runPostAdmissionSeatResume,
20
+ resumeTurnRequestProjectionOptions,
18
21
  } from "./post-admission.ts";
19
- import { markRunAdmitted } from "./run-lifecycle.ts";
22
+ import {
23
+ loadResumableDoctorRun,
24
+ markRunAdmitted,
25
+ type PublicResumeRequest,
26
+ } from "./run-lifecycle.ts";
20
27
  import {
21
28
  presentStructuralRejection,
22
29
  trySettleDoctorTerminalResult,
@@ -106,11 +113,48 @@ export async function runPublicDoctor(
106
113
  env,
107
114
  io,
108
115
  request: turnRequest,
109
- adapters: {
110
- trySettle: (admitted, authority) => trySettleDoctorTerminalResult(admitted, authority),
111
- shouldPresentSettled: (terminal) =>
112
- isLawfulTypedTerminalOutcome(terminal.roleOutcome),
113
- },
116
+ adapters: doctorAdapters(),
117
+ ...(env.engine === undefined ? {} : { effectiveEngine: env.engine }),
118
+ });
119
+ }
120
+
121
+ function doctorAdapters(): PostAdmissionAdapters<AdmittedDoctorInvocation> {
122
+ return {
123
+ trySettle: (admitted, authority) => trySettleDoctorTerminalResult(admitted, authority),
124
+ shouldPresentSettled: (terminal) =>
125
+ isLawfulTypedTerminalOutcome(terminal.roleOutcome),
126
+ };
127
+ }
128
+
129
+ /**
130
+ * Resume a previously admitted Doctor run (#633). Issue + retained case
131
+ * identity restore from the durable admitted request; the session principal reopens.
132
+ */
133
+ export async function runPublicDoctorResume(
134
+ request: PublicResumeRequest,
135
+ env: DoctorRunEnv,
136
+ io: CliIo,
137
+ ): Promise<{
138
+ exitCode: number;
139
+ admitted?: AdmittedDoctorInvocation;
140
+ terminal?: TerminalResult;
141
+ }> {
142
+ return await runPostAdmissionSeatResume({
143
+ request,
144
+ env,
145
+ io,
146
+ load: () =>
147
+ loadResumableDoctorRun(
148
+ env.home,
149
+ request.runId,
150
+ env.principalAuthority,
151
+ ),
152
+ buildTurnRequest: (admitted) =>
153
+ buildDoctorTurnRequest(
154
+ admitted,
155
+ resumeTurnRequestProjectionOptions(admitted, request, env),
156
+ ),
157
+ adapters: doctorAdapters(),
114
158
  ...(env.engine === undefined ? {} : { effectiveEngine: env.engine }),
115
159
  });
116
160
  }
@@ -47,6 +47,7 @@ import {
47
47
  runPostAdmissionResumable,
48
48
  type PostAdmissionAdapters,
49
49
  type PostAdmissionEnv,
50
+ resumeTurnRequestProjectionOptions,
50
51
  } from "./post-admission.ts";
51
52
 
52
53
  export type FixerRunEnv = PostAdmissionEnv & {
@@ -264,25 +265,10 @@ export async function runPublicFixerResume(
264
265
  )) as { exitCode: number; admitted: AdmittedFixerInvocation; terminal: TerminalResult };
265
266
  }
266
267
 
267
- const turnRequest = buildFixerTurnRequest(admitted, {
268
- packageRoot: env.packageRoot,
269
- home: env.home,
270
- agentDir: env.agentDir,
271
- ...(env.model === undefined ? {} : { model: env.model }),
272
- ...(env.engine === undefined ? {} : { engine: env.engine }),
273
- ...(env.timeoutMs === undefined ? {} : { timeoutMs: env.timeoutMs }),
274
- ...(admitted.correlationId === undefined && env.correlationId === undefined
275
- ? {}
276
- : { correlationId: admitted.correlationId ?? env.correlationId }),
277
- continuation: {
278
- kind: "resume",
279
- prompt: buildResumeContinuationPrompt({
280
- packageRoot: env.packageRoot,
281
- ...(env.engine === undefined ? {} : { engine: env.engine }),
282
- ...(request.message === undefined ? {} : { message: request.message }),
283
- }),
284
- },
285
- });
268
+ const turnRequest = buildFixerTurnRequest(
269
+ admitted,
270
+ resumeTurnRequestProjectionOptions(admitted, request, env),
271
+ );
286
272
 
287
273
  return await runPostAdmissionManualResume({
288
274
  admitted,
@@ -13,14 +13,14 @@ import {
13
13
  type ParseGleanerLeftArgvResult,
14
14
  } from "./invocation.ts";
15
15
  import {
16
- runPostAdmissionManualResume,
17
16
  runPostAdmissionOneShot,
18
17
  type PostAdmissionEnv,
18
+ runPostAdmissionSeatResume,
19
+ resumeTurnRequestProjectionOptions,
19
20
  } from "./post-admission.ts";
20
21
  import {
21
22
  loadResumableGleanerLeftRun,
22
23
  markRunAdmitted,
23
- buildResumeContinuationPrompt,
24
24
  type PublicResumeRequest,
25
25
  } from "./run-lifecycle.ts";
26
26
  import {
@@ -143,47 +143,21 @@ export async function runPublicGleanerLeftResume(
143
143
  admitted?: AdmittedGleanerLeftInvocation;
144
144
  terminal?: TerminalResult;
145
145
  }> {
146
- let loaded;
147
- try {
148
- loaded = await loadResumableGleanerLeftRun(
146
+ return await runPostAdmissionSeatResume({
147
+ request,
148
+ env,
149
+ io,
150
+ load: () =>
151
+ loadResumableGleanerLeftRun(
149
152
  env.home,
150
153
  request.runId,
151
154
  env.principalAuthority,
152
- );
153
- } catch (error) {
154
- if (error instanceof CliUsageError) {
155
- presentStructuralRejection(error, io);
156
- return { exitCode: 2 };
157
- }
158
- throw error;
159
- }
160
-
161
- const { admitted } = loaded;
162
- const turnRequest = buildGleanerLeftTurnRequest(admitted, {
163
- packageRoot: env.packageRoot,
164
- home: env.home,
165
- agentDir: env.agentDir,
166
- ...(env.model === undefined ? {} : { model: env.model }),
167
- ...(env.engine === undefined ? {} : { engine: env.engine }),
168
- ...(env.timeoutMs === undefined ? {} : { timeoutMs: env.timeoutMs }),
169
- ...(admitted.correlationId === undefined && env.correlationId === undefined
170
- ? {}
171
- : { correlationId: admitted.correlationId ?? env.correlationId }),
172
- continuation: {
173
- kind: "resume",
174
- prompt: buildResumeContinuationPrompt({
175
- packageRoot: env.packageRoot,
176
- ...(env.engine === undefined ? {} : { engine: env.engine }),
177
- ...(request.message === undefined ? {} : { message: request.message }),
178
- }),
179
- },
180
- });
181
-
182
- return await runPostAdmissionManualResume({
183
- admitted,
184
- env,
185
- io,
186
- request: turnRequest,
155
+ ),
156
+ buildTurnRequest: (admitted) =>
157
+ buildGleanerLeftTurnRequest(
158
+ admitted,
159
+ resumeTurnRequestProjectionOptions(admitted, request, env),
160
+ ),
187
161
  adapters: gleanerLeftAdapters(),
188
162
  ...(env.engine === undefined ? {} : { effectiveEngine: env.engine }),
189
163
  });