@akagilnc/pi-workflow-roles 0.1.2521 → 0.1.2653-next.71811ca

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 (109) hide show
  1. package/README.md +129 -39
  2. package/README.zh-CN.md +128 -39
  3. package/dist/activation-ledger-topology.js +1 -1
  4. package/dist/archivist-record-entry.js +47 -26
  5. package/dist/auditor-dossier-tool.js +3 -1
  6. package/dist/compliance-transport.js +17 -26
  7. package/dist/doctor-contracts.js +1 -2
  8. package/dist/dossier-resolution.js +4 -8
  9. package/dist/engine-detour-tool.js +33 -8
  10. package/dist/engine-detour.js +1 -0
  11. package/dist/evidence-child-executor.js +277 -424
  12. package/dist/host-contracts.js +22 -0
  13. package/dist/institutional-resolution.js +88 -0
  14. package/dist/merger-contracts.js +1 -2
  15. package/dist/navigator-attendance.js +16 -0
  16. package/dist/notary-contracts.js +2 -3
  17. package/dist/package-contracts/fixer-output.js +1 -2
  18. package/dist/packaged-role-registry.js +102 -9
  19. package/dist/pi/in-process-session.js +671 -0
  20. package/dist/public-cli/config.js +7 -5
  21. package/dist/public-cli/main.js +3767 -4113
  22. package/dist/reviewer-child-executor.js +6 -1
  23. package/dist/session-opening-materials.js +10 -38
  24. package/dist/sitian-appender.js +146 -0
  25. package/dist/sitian-contracts.js +21 -0
  26. package/dist/sitian-facade.js +15 -0
  27. package/dist/sitian-reader.js +52 -0
  28. package/extensions/role-runtime.ts +9 -7
  29. package/package.json +5 -5
  30. package/resources/engines/cursor.md +12 -26
  31. package/resources/engines/hermes.md +2 -23
  32. package/resources/engines/opus.md +1 -16
  33. package/resources/navigator-route-playbook.md +2 -2
  34. package/scripts/build-package.mjs +0 -1
  35. package/souls/quality-law.md +1 -1
  36. package/src/activation-ledger-topology.ts +1 -1
  37. package/src/archivist-record-entry.ts +57 -45
  38. package/src/auditor-dossier-tool.ts +4 -2
  39. package/src/canonical-skill-binding.ts +37 -27
  40. package/src/collector-role.ts +11 -20
  41. package/src/collector-tool-schemas.ts +1 -4
  42. package/src/compliance-transport.ts +19 -44
  43. package/src/doctor-auditor.ts +1 -5
  44. package/src/doctor-contracts.ts +1 -4
  45. package/src/doctor-role.ts +31 -8
  46. package/src/dossier-resolution.ts +8 -8
  47. package/src/engine-detour-tool.ts +48 -19
  48. package/src/engine-detour.ts +3 -0
  49. package/src/evidence-child-executor.ts +277 -485
  50. package/src/factory-board.ts +3 -3
  51. package/src/gatekeeper-role.ts +21 -10
  52. package/src/host-contracts.ts +386 -0
  53. package/src/in-process-session.ts +1 -115
  54. package/src/institutional-resolution.ts +135 -0
  55. package/src/judge-auditor.ts +1 -5
  56. package/src/judge-role.ts +37 -51
  57. package/src/merger-contracts.ts +1 -4
  58. package/src/merger-role.ts +7 -11
  59. package/src/navigator-attendance.ts +20 -1
  60. package/src/notary-contracts.ts +8 -11
  61. package/src/notary-role.ts +7 -23
  62. package/src/notary-source-run.ts +4 -3
  63. package/src/package-contracts/fixer-output.ts +1 -4
  64. package/src/package-resources/method-skill-binding.ts +10 -34
  65. package/src/packaged-role-registry.ts +122 -12
  66. package/src/pi/adapter.ts +192 -0
  67. package/src/pi/durable-principal.ts +98 -0
  68. package/src/pi/in-process-session.ts +819 -0
  69. package/src/pi/known-failure.ts +77 -0
  70. package/src/pi/pi-normalization.ts +284 -0
  71. package/src/pi/role-turn-host.ts +459 -0
  72. package/src/public-cli/auto-resume.ts +42 -44
  73. package/src/public-cli/cli.ts +171 -257
  74. package/src/public-cli/coder-run.ts +115 -433
  75. package/src/public-cli/collector-run.ts +62 -314
  76. package/src/public-cli/config.ts +7 -5
  77. package/src/public-cli/doctor-run.ts +41 -52
  78. package/src/public-cli/fixer-run.ts +122 -427
  79. package/src/public-cli/invocation.ts +287 -96
  80. package/src/public-cli/judge-run.ts +92 -422
  81. package/src/public-cli/merger-run.ts +167 -429
  82. package/src/public-cli/notary-run.ts +41 -47
  83. package/src/public-cli/option-definitions.ts +136 -3
  84. package/src/public-cli/post-admission.ts +497 -0
  85. package/src/public-cli/public-run-credentials.ts +4 -4
  86. package/src/public-cli/reviewer-dispatch-rejection.ts +106 -0
  87. package/src/public-cli/reviewer-run.ts +132 -449
  88. package/src/public-cli/run-lifecycle.ts +339 -327
  89. package/src/public-cli/settlement.ts +251 -134
  90. package/src/public-cli/terminal.ts +3 -9
  91. package/src/public-cli/turn-request.ts +87 -0
  92. package/src/reviewer-child-executor.ts +9 -1
  93. package/src/reviewer-role.ts +11 -20
  94. package/src/role-runtime.ts +129 -78
  95. package/src/session-opening-materials.ts +25 -39
  96. package/src/sitian-appender.ts +171 -0
  97. package/src/sitian-contracts.ts +106 -0
  98. package/src/sitian-facade.ts +18 -0
  99. package/src/sitian-reader.ts +62 -0
  100. package/src/worker-role.ts +42 -40
  101. package/src/worker-submission-gates.ts +33 -0
  102. package/dist/archivist-role-run-coordinates.js +0 -28
  103. package/dist/package-contracts/terminating-infrastructure.js +0 -90
  104. package/resources/engines/sonnet.md +0 -27
  105. package/resources/engines/zcode.md +0 -63
  106. package/src/archivist-role-run-coordinates.ts +0 -45
  107. package/src/package-contracts/terminating-infrastructure.ts +0 -132
  108. package/src/public-cli/explicit-internal.ts +0 -427
  109. package/src/public-cli/one-shot-dispatch.ts +0 -300
@@ -1,19 +1,10 @@
1
1
  /**
2
2
  * Public Collector Role run: admit a structured PR target → explicit Internal activate
3
- * → settle Terminal result (#112). One-shot; no resume path (Collector rejects
4
- * session resume/fork/reload). Failure settlement reuses the #107 shared owner.
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.
5
5
  */
6
- import { writeFile } from "node:fs/promises";
7
- import { join } from "node:path";
8
-
9
- import { applyEngineChildEnv } from "../engine-detour.ts";
6
+ import type { DurablePrincipalAuthority, RoleTurnRequest } from "../host-contracts.ts";
10
7
  import { engineSessionMaterialFromOptions } from "../package-resources/engine-material.ts";
11
- import {
12
- runExplicitInternalActivation,
13
- type ExplicitInternalKnownFailure,
14
- type ExplicitInternalPiRunner,
15
- type ExplicitInternalPiResult,
16
- } from "./explicit-internal.ts";
17
8
  import { CliUsageError } from "./cli-errors.ts";
18
9
  import {
19
10
  admitCollectorInvocation,
@@ -22,300 +13,43 @@ import {
22
13
  type ParseCollectorArgvResult,
23
14
  } from "./invocation.ts";
24
15
  import {
25
- buildSeatModelCliArgs,
26
- type CredentialProviders,
27
- type SeatModelConfig,
28
- } from "./config.ts";
29
- import {
30
- missingCredentialPreDispatchFailure,
31
- postRunMissingCredentialFailure,
32
- } from "./public-run-credentials.ts";
33
- import {
34
- acquireRunWriterLease,
35
- clearTypedProviderHttpObservation,
36
- markRunAdmitted,
37
- markRunRunning,
38
- markRunTerminal,
39
- RunWriterLeaseHeldError,
40
- type RunWriterLease,
41
- } from "./run-lifecycle.ts";
16
+ runPostAdmissionOneShot,
17
+ type PostAdmissionEnv,
18
+ } from "./post-admission.ts";
19
+ import { markRunAdmitted } from "./run-lifecycle.ts";
42
20
  import {
43
- classifyPostAdmissionFailure,
44
- exitCodeForTerminalOutcome,
45
- formatTerminalResult,
46
- inspectJudgeSession,
47
- presentFailureTerminal,
48
21
  presentStructuralRejection,
49
- explicitInternalKnownFailureClassificationInput,
50
22
  readCollectorInfrastructureFailure,
51
- resolveAuditedRunnerKnownFailure,
52
- settleFailureTerminalResult,
53
23
  trySettleCollectorTerminalResult,
54
24
  } from "./settlement.ts";
55
25
  import type { CliIo } from "./cli-io.ts";
56
- import type {
57
- ControlledFailureCause,
58
- TerminalResult,
59
- } from "./terminal.ts";
26
+ import type { TerminalResult } from "./terminal.ts";
27
+ import {
28
+ projectRoleTurnRequest,
29
+ type RoleTurnRequestProjectionOptions,
30
+ } from "./turn-request.ts";
60
31
 
61
- export type CollectorRunEnv = {
62
- home: string;
63
- agentDir: string;
64
- packageRoot: string;
65
- cwd: string;
66
- correlationId?: string;
67
- piRunner?: ExplicitInternalPiRunner;
68
- model?: SeatModelConfig;
69
- /** Optional labor engine name (config→activation; session material + env signal). */
70
- engine?: string;
71
- credentials?: CredentialProviders;
32
+ export type CollectorRunEnv = PostAdmissionEnv & {
72
33
  createRunId?: () => string;
73
- extraPiArgs?: readonly string[];
74
- timeoutMs?: number;
75
34
  };
76
35
 
77
-
78
- /**
79
- * Build Internal activation extra-args for an admitted Collector run.
80
- * Always --no-skills (Collector forbids every Skill). Session under #78 book.
81
- */
82
- export function buildCollectorActivationExtraArgs(
36
+ /** Project admitted invocation onto the host-neutral turn request. */
37
+ export function buildCollectorTurnRequest(
83
38
  admitted: AdmittedCollectorInvocation,
84
- options: {
85
- model?: SeatModelConfig;
86
- engine?: string;
87
- packageRoot?: string;
88
- extraPiArgs?: readonly string[];
89
- } = {},
90
- ): string[] {
91
- const prompt = buildCollectorTransportPrompt(
39
+ options: RoleTurnRequestProjectionOptions,
40
+ ): RoleTurnRequest {
41
+ return projectRoleTurnRequest(
92
42
  admitted,
93
- engineSessionMaterialFromOptions(options),
94
- );
95
- return [
96
- "--no-skills",
97
- "--no-prompt-templates",
98
- "--no-themes",
99
- "--no-context-files",
100
- "--session",
101
- admitted.sessionFile,
102
- "--session-dir",
103
- admitted.sessionDirectory,
104
- ...(options.extraPiArgs ?? []),
105
- "--ak-role",
106
- "collector",
107
- "--ak-collector-repo",
108
- admitted.repository.display,
109
- "--ak-collector-pr",
110
- String(admitted.prNumber),
111
- ...(admitted.requestManifestPath === undefined
112
- ? []
113
- : ["--ak-collector-request-manifest", admitted.requestManifestPath]),
114
- "--mode",
115
- "json",
116
- ...buildSeatModelCliArgs(options.model),
117
- prompt,
118
- ];
119
- }
120
-
121
- async function presentControlledFailure(
122
- admitted: AdmittedCollectorInvocation,
123
- failureInput: {
124
- timedOut: boolean;
125
- code: number | null;
126
- stderr: string;
127
- thrown?: unknown;
128
- knownFailure?: ExplicitInternalKnownFailure;
129
- knownCause?: ControlledFailureCause;
130
- knownIdentity?: {
131
- readonly name?: string;
132
- readonly code?: string | number;
133
- };
134
- knownDiagnostic?: string;
135
- },
136
- io: CliIo,
137
- ): Promise<{
138
- exitCode: number;
139
- admitted: AdmittedCollectorInvocation;
140
- terminal: TerminalResult;
141
- }> {
142
- const hasThrown = Object.hasOwn(failureInput, "thrown");
143
- const session =
144
- !hasThrown &&
145
- !failureInput.timedOut &&
146
- failureInput.knownFailure === undefined &&
147
- failureInput.knownCause === undefined
148
- ? await inspectJudgeSession(admitted.sessionFile)
149
- : undefined;
150
- const failure = classifyPostAdmissionFailure({
151
- timedOut: failureInput.timedOut,
152
- code: failureInput.code,
153
- stderr: failureInput.stderr,
154
- ...(hasThrown ? { thrown: failureInput.thrown } : {}),
155
- ...explicitInternalKnownFailureClassificationInput(failureInput.knownFailure),
156
- ...(failureInput.knownCause === undefined
157
- ? {}
158
- : { knownCause: failureInput.knownCause }),
159
- ...(failureInput.knownIdentity === undefined
160
- ? {}
161
- : { knownIdentity: failureInput.knownIdentity }),
162
- ...(failureInput.knownDiagnostic === undefined
163
- ? {}
164
- : { knownDiagnostic: failureInput.knownDiagnostic }),
165
- ...(session === undefined ? {} : { session }),
166
- });
167
-
168
- // Collector does not support resume/fork/reload — always terminal.
169
- await markRunTerminal(admitted.runDirectory).catch(() => undefined);
170
-
171
- const terminal = await settleFailureTerminalResult(admitted, failure);
172
- presentFailureTerminal(terminal, io);
173
- return {
174
- exitCode: exitCodeForTerminalOutcome(terminal.roleOutcome),
175
- admitted,
176
- terminal,
177
- };
178
- }
179
-
180
- async function dispatchAdmittedCollector(input: {
181
- admitted: AdmittedCollectorInvocation;
182
- env: CollectorRunEnv;
183
- io: CliIo;
184
- extraArgs: string[];
185
- lease: RunWriterLease;
186
- effectiveEngine?: string;
187
- }): Promise<{
188
- exitCode: number;
189
- admitted: AdmittedCollectorInvocation;
190
- terminal?: TerminalResult;
191
- }> {
192
- const { admitted, env, io, extraArgs, lease, effectiveEngine } = input;
193
- try {
194
- const missingCredential = missingCredentialPreDispatchFailure(
195
- env.model,
196
- env.credentials,
197
- );
198
- if (missingCredential !== undefined) {
199
- return await presentControlledFailure(
200
- admitted,
201
- missingCredential,
202
- io,
203
- );
204
- }
205
- await markRunRunning(admitted.runDirectory, env.model, effectiveEngine);
206
- await clearTypedProviderHttpObservation(admitted.runDirectory);
207
-
208
- const childEnv: NodeJS.ProcessEnv = {
209
- ...process.env,
210
- HOME: env.home,
211
- PI_CODING_AGENT_DIR: env.agentDir,
212
- AK_ROLE_RUN_DIR: admitted.runDirectory,
213
- };
214
- applyEngineChildEnv(childEnv, env.engine);
215
- const correlationId = admitted.correlationId ?? env.correlationId;
216
- if (correlationId !== undefined && correlationId.trim() !== "") {
217
- childEnv.AK_CORRELATION_ID = correlationId;
218
- }
219
-
220
- let result: ExplicitInternalPiResult;
221
- try {
222
- result = await runExplicitInternalActivation({
223
- packageRoot: env.packageRoot,
224
- extraArgs,
225
- cwd: admitted.projectRoot,
226
- home: env.home,
227
- agentDir: env.agentDir,
228
- env: childEnv,
229
- timeoutMs: env.timeoutMs,
230
- ...(env.piRunner === undefined ? {} : { runner: env.piRunner }),
231
- });
232
- } catch (error) {
233
- return await presentControlledFailure(
234
- admitted,
235
- {
236
- timedOut: false,
237
- code: null,
238
- stderr: "",
239
- thrown: error,
240
- },
241
- io,
242
- );
243
- }
244
-
245
- try {
246
- await writeFile(
247
- join(admitted.runDirectory, "stderr.log"),
248
- result.stderr,
249
- "utf8",
250
- );
251
- } catch {
252
- // continue to lawful / controlled-failure settlement
253
- }
254
-
255
- let lawful: TerminalResult | undefined;
256
- try {
257
- lawful = await trySettleCollectorTerminalResult(admitted);
258
- } catch (error) {
259
- return await presentControlledFailure(
260
- admitted,
261
- {
262
- timedOut: false,
263
- code: result.code,
264
- stderr: result.stderr,
265
- thrown: error,
266
- },
267
- io,
268
- );
269
- }
270
- if (lawful !== undefined) {
271
- await markRunTerminal(admitted.runDirectory).catch(() => undefined);
272
- io.stdout(formatTerminalResult(lawful));
273
- return {
274
- exitCode: exitCodeForTerminalOutcome(lawful.roleOutcome),
275
- admitted,
276
- terminal: lawful,
277
- };
278
- }
279
-
280
- // Prefer Collector infrastructure tool failure already on the session principal
281
- // (e.g. observe HTTP 404) over a later secondary provider-stop after abort.
282
- const infrastructureFailure = await readCollectorInfrastructureFailure(
283
- admitted.sessionFile,
284
- );
285
- const credentialFailure = postRunMissingCredentialFailure(
286
- result,
287
- env.model,
288
- env.credentials,
289
- );
290
- const knownFailure = await resolveAuditedRunnerKnownFailure({
291
- runner:
292
- result.knownFailure ??
293
- (infrastructureFailure === undefined
294
- ? undefined
295
- : {
296
- cause: infrastructureFailure.cause,
297
- diagnostic: infrastructureFailure.diagnostic,
298
- ...(infrastructureFailure.identity === undefined
299
- ? {}
300
- : { identity: infrastructureFailure.identity }),
301
- }),
302
- sessionFile: admitted.sessionFile,
303
- credential: credentialFailure,
304
- runDirectory: admitted.runDirectory,
305
- });
306
- return await presentControlledFailure(
307
- admitted,
308
- {
309
- timedOut: result.timedOut,
310
- code: result.code,
311
- stderr: result.stderr,
312
- ...(knownFailure === undefined ? {} : { knownFailure }),
43
+ {
44
+ activation: {
45
+ role: "collector" as const,
46
+ repo: admitted.repository.display,
47
+ pr: String(admitted.prNumber),
48
+ ...(admitted.requestManifestPath === undefined ? {} : { requestManifestPath: admitted.requestManifestPath }),
313
49
  },
314
- io,
315
- );
316
- } finally {
317
- await lease.release();
318
- }
50
+ },
51
+ options,
52
+ );
319
53
  }
320
54
 
321
55
  export async function runPublicCollector(
@@ -333,6 +67,7 @@ export async function runPublicCollector(
333
67
  const parsed = parseCollectorArgv(argv);
334
68
  admitted = await admitCollectorInvocation({
335
69
  home: env.home,
70
+ principalAuthority: env.principalAuthority,
336
71
  cwd: env.cwd,
337
72
  prNumber: parsed.prNumber,
338
73
  instruction: parsed.instruction,
@@ -351,35 +86,48 @@ export async function runPublicCollector(
351
86
  throw error;
352
87
  }
353
88
 
354
- await markRunAdmitted(admitted);
355
-
356
- let lease: RunWriterLease;
357
- try {
358
- lease = await acquireRunWriterLease(admitted.runDirectory, (diagnostic) => io.stderr(diagnostic));
359
- } catch (error) {
360
- if (error instanceof RunWriterLeaseHeldError) {
361
- presentStructuralRejection(error, io);
362
- return { exitCode: 2 };
363
- }
364
- throw error;
365
- }
89
+ await markRunAdmitted(admitted, env.principalAuthority);
366
90
 
367
- const extraArgs = buildCollectorActivationExtraArgs(admitted, {
91
+ const turnRequest = buildCollectorTurnRequest(admitted, {
368
92
  packageRoot: env.packageRoot,
93
+ home: env.home,
94
+ agentDir: env.agentDir,
369
95
  ...(env.model === undefined ? {} : { model: env.model }),
370
96
  ...(env.engine === undefined ? {} : { engine: env.engine }),
371
- ...(env.extraPiArgs === undefined ? {} : { extraPiArgs: env.extraPiArgs }),
97
+ ...(env.timeoutMs === undefined ? {} : { timeoutMs: env.timeoutMs }),
98
+ ...(admitted.correlationId === undefined && env.correlationId === undefined
99
+ ? {}
100
+ : { correlationId: admitted.correlationId ?? env.correlationId }),
101
+ continuation: {
102
+ kind: "initial",
103
+ prompt: buildCollectorTransportPrompt(admitted, engineSessionMaterialFromOptions({ ...(env.engine === undefined ? {} : { engine: env.engine }), packageRoot: env.packageRoot })),
104
+ },
372
105
  });
373
106
 
374
- return await dispatchAdmittedCollector({
107
+ return await runPostAdmissionOneShot({
375
108
  admitted,
376
- env: {
377
- ...env,
378
- ...(admitted.correlationId === undefined ? {} : { correlationId: admitted.correlationId }),
379
- },
109
+ env,
380
110
  io,
381
- extraArgs,
382
- lease,
111
+ 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
+ },
130
+ },
383
131
  ...(env.engine === undefined ? {} : { effectiveEngine: env.engine }),
384
132
  });
385
133
  }
@@ -2,7 +2,6 @@
2
2
  * Persistent and effective per-seat model/thinking configuration for ak-role.
3
3
  */
4
4
  import { mkdir, readFile, writeFile } from "node:fs/promises";
5
- import { homedir } from "node:os";
6
5
  import { dirname, join } from "node:path";
7
6
 
8
7
  import { assertLegalEngineName } from "../package-resources/engine-material.ts";
@@ -87,7 +86,7 @@ export type InvocationModelOverride = {
87
86
  engine?: string;
88
87
  };
89
88
 
90
- const THINKING_LEVELS = new Set<PublicThinkingLevel>([
89
+ export const THINKING_LEVELS = new Set<PublicThinkingLevel>([
91
90
  "off",
92
91
  "minimal",
93
92
  "low",
@@ -97,12 +96,15 @@ const THINKING_LEVELS = new Set<PublicThinkingLevel>([
97
96
  "max",
98
97
  ]);
99
98
 
100
- export function publicCliConfigPath(home: string = homedir()): string {
99
+ export function publicCliConfigPath(home: string): string {
100
+ if (typeof home !== "string" || home.trim() === "") {
101
+ throw new Error("home must be explicitly provided");
102
+ }
101
103
  return join(home, ".ak-roles", "public-cli.json");
102
104
  }
103
105
 
104
106
  export async function loadPublicCliConfig(
105
- home: string = homedir(),
107
+ home: string,
106
108
  ): Promise<PublicCliConfig> {
107
109
  const path = publicCliConfigPath(home);
108
110
  try {
@@ -122,7 +124,7 @@ export async function loadPublicCliConfig(
122
124
 
123
125
  export async function savePublicCliConfig(
124
126
  config: PublicCliConfig,
125
- home: string = homedir(),
127
+ home: string,
126
128
  ): Promise<void> {
127
129
  const path = publicCliConfigPath(home);
128
130
  await mkdir(dirname(path), { recursive: true });
@@ -1,24 +1,22 @@
1
1
  /**
2
- * Public Doctor Role run: admit Issue → retained case via #78 → shared one-shot
3
- * dispatch → settle Terminal result (#113). Lifecycle is the shared
4
- * Doctor-isomorphic seam; this module keeps only Doctor adapters.
2
+ * Public Doctor Role run: admit Issue → retained case via #78 → shared post-admission
3
+ * coordinator → settle Terminal result (#113 / #517). Lifecycle is the shared
4
+ * post-admission seam; this module keeps only Doctor adapters.
5
5
  */
6
+ import type { DurablePrincipalAuthority, RoleTurnRequest } from "../host-contracts.ts";
6
7
  import { engineSessionMaterialFromOptions } from "../package-resources/engine-material.ts";
7
8
  import { CliUsageError } from "./cli-errors.ts";
8
9
  import {
9
10
  admitDoctorInvocation,
10
11
  buildDoctorTransportPrompt,
11
12
  type AdmittedDoctorInvocation,
12
- type ParseDoctorArgvResult,
13
+ type ParseDoctorArgvResult
13
14
  } from "./invocation.ts";
14
15
  import {
15
- buildSeatModelCliArgs,
16
- type SeatModelConfig,
17
- } from "./config.ts";
18
- import {
19
- runAdmittedOneShotRole,
20
- type OneShotRunEnv,
21
- } from "./one-shot-dispatch.ts";
16
+ runPostAdmissionOneShot,
17
+ type PostAdmissionEnv,
18
+ } from "./post-admission.ts";
19
+ import { markRunAdmitted } from "./run-lifecycle.ts";
22
20
  import {
23
21
  presentStructuralRejection,
24
22
  trySettleDoctorTerminalResult,
@@ -28,49 +26,28 @@ import {
28
26
  isLawfulTypedTerminalOutcome,
29
27
  type TerminalResult,
30
28
  } from "./terminal.ts";
29
+ import {
30
+ projectRoleTurnRequest,
31
+ type RoleTurnRequestProjectionOptions,
32
+ } from "./turn-request.ts";
31
33
 
32
- export type DoctorRunEnv = OneShotRunEnv & {
34
+ export type DoctorRunEnv = PostAdmissionEnv & {
35
+ principalAuthority: DurablePrincipalAuthority;
33
36
  createRunId?: () => string;
34
- extraPiArgs?: readonly string[];
35
37
  };
36
38
 
37
- /**
38
- * Build Internal activation extra-args for an admitted Doctor run.
39
- * Always --no-skills (Doctor forbids every Skill). Session under #78 book.
40
- * Case path is the retained runs root — never a legacy case packet.
41
- */
42
- export function buildDoctorActivationExtraArgs(
39
+ /** Project admitted invocation onto the host-neutral turn request. */
40
+ export function buildDoctorTurnRequest(
43
41
  admitted: AdmittedDoctorInvocation,
44
- options: {
45
- model?: SeatModelConfig;
46
- engine?: string;
47
- packageRoot?: string;
48
- extraPiArgs?: readonly string[];
49
- } = {},
50
- ): string[] {
51
- const prompt = buildDoctorTransportPrompt(
42
+ options: RoleTurnRequestProjectionOptions,
43
+ ): RoleTurnRequest {
44
+ return projectRoleTurnRequest(
52
45
  admitted,
53
- engineSessionMaterialFromOptions(options),
46
+ {
47
+ activation: { role: "doctor" as const, casePath: admitted.caseRunsPath },
48
+ },
49
+ options,
54
50
  );
55
- return [
56
- "--no-skills",
57
- "--no-prompt-templates",
58
- "--no-themes",
59
- "--no-context-files",
60
- "--session",
61
- admitted.sessionFile,
62
- "--session-dir",
63
- admitted.sessionDirectory,
64
- ...(options.extraPiArgs ?? []),
65
- "--ak-role",
66
- "doctor",
67
- "--ak-doctor-case",
68
- admitted.caseRunsPath,
69
- "--mode",
70
- "json",
71
- ...buildSeatModelCliArgs(options.model),
72
- prompt,
73
- ];
74
51
  }
75
52
 
76
53
  export async function runPublicDoctor(
@@ -88,6 +65,7 @@ export async function runPublicDoctor(
88
65
  const parsed = parseDoctorArgv(argv);
89
66
  admitted = await admitDoctorInvocation({
90
67
  home: env.home,
68
+ principalAuthority: env.principalAuthority,
91
69
  cwd: env.cwd,
92
70
  issueNumber: parsed.issueNumber,
93
71
  instruction: parsed.instruction,
@@ -105,20 +83,31 @@ export async function runPublicDoctor(
105
83
  throw error;
106
84
  }
107
85
 
108
- const extraArgs = buildDoctorActivationExtraArgs(admitted, {
86
+ await markRunAdmitted(admitted, env.principalAuthority);
87
+
88
+ const turnRequest = buildDoctorTurnRequest(admitted, {
109
89
  packageRoot: env.packageRoot,
90
+ home: env.home,
91
+ agentDir: env.agentDir,
110
92
  ...(env.model === undefined ? {} : { model: env.model }),
111
93
  ...(env.engine === undefined ? {} : { engine: env.engine }),
112
- ...(env.extraPiArgs === undefined ? {} : { extraPiArgs: env.extraPiArgs }),
94
+ ...(env.timeoutMs === undefined ? {} : { timeoutMs: env.timeoutMs }),
95
+ ...(env.correlationId === undefined || env.correlationId.trim() === ""
96
+ ? {}
97
+ : { correlationId: env.correlationId }),
98
+ continuation: {
99
+ kind: "initial",
100
+ prompt: buildDoctorTransportPrompt(admitted, engineSessionMaterialFromOptions({ ...(env.engine === undefined ? {} : { engine: env.engine }), packageRoot: env.packageRoot })),
101
+ },
113
102
  });
114
103
 
115
- return await runAdmittedOneShotRole({
104
+ return await runPostAdmissionOneShot({
116
105
  admitted,
117
106
  env,
118
107
  io,
119
- extraArgs,
108
+ request: turnRequest,
120
109
  adapters: {
121
- trySettle: trySettleDoctorTerminalResult,
110
+ trySettle: (admitted, authority) => trySettleDoctorTerminalResult(admitted, authority),
122
111
  shouldPresentSettled: (terminal) =>
123
112
  isLawfulTypedTerminalOutcome(terminal.roleOutcome),
124
113
  },