@akagilnc/pi-workflow-roles 0.1.1751

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 (192) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +104 -0
  3. package/README.zh-CN.md +133 -0
  4. package/THIRD_PARTY_NOTICES.md +60 -0
  5. package/dist/activation-ledger-git.js +68 -0
  6. package/dist/activation-ledger-session.js +120 -0
  7. package/dist/activation-ledger-topology.js +239 -0
  8. package/dist/activation-reconciliation.js +61 -0
  9. package/dist/audit-escalation.js +108 -0
  10. package/dist/auditor-dossier-tool.js +35 -0
  11. package/dist/canonical-json.js +78 -0
  12. package/dist/compliance-transport.js +77 -0
  13. package/dist/doctor-contracts.js +172 -0
  14. package/dist/dossier-resolution.js +103 -0
  15. package/dist/evidence-child-executor.js +661 -0
  16. package/dist/exact-utf8.js +12 -0
  17. package/dist/git-object-id.js +7 -0
  18. package/dist/in-process-session.js +50 -0
  19. package/dist/merger-contracts.js +76 -0
  20. package/dist/navigator-attendance.js +995 -0
  21. package/dist/navigator-invocation-identity.js +220 -0
  22. package/dist/open-tool-schema.js +39 -0
  23. package/dist/package-contracts/collector-output.js +50 -0
  24. package/dist/package-contracts/fixer-output.js +72 -0
  25. package/dist/package-contracts/fixer-packet.js +77 -0
  26. package/dist/package-contracts/judge-output.js +17 -0
  27. package/dist/package-contracts/reviewer-output.js +82 -0
  28. package/dist/package-contracts/terminating-tools.js +173 -0
  29. package/dist/package-contracts/worker-output.js +13 -0
  30. package/dist/package-owned-tool-idle.js +104 -0
  31. package/dist/packaged-role-registry.js +34 -0
  32. package/dist/public-cli/main.js +23867 -0
  33. package/dist/public-command-renderer.js +20 -0
  34. package/dist/reviewer-agent.js +93 -0
  35. package/dist/reviewer-child-executor.js +23 -0
  36. package/dist/reviewer-construction.js +95 -0
  37. package/dist/reviewer-dispatch.js +77 -0
  38. package/dist/reviewer-execution-ledger.js +160 -0
  39. package/dist/reviewer-failure-diagnostic.js +17 -0
  40. package/dist/reviewer-git-snapshot.js +38 -0
  41. package/dist/reviewer-pinned-git.js +146 -0
  42. package/dist/reviewer-preflight-error.js +15 -0
  43. package/dist/reviewer-prompt-identity.js +10 -0
  44. package/dist/reviewer-scope-prompt.js +21 -0
  45. package/dist/reviewer-workspace.js +151 -0
  46. package/dist/sha256.js +5 -0
  47. package/dist/sitian-record-entry.js +33 -0
  48. package/dist/stderr-jsonl.js +26 -0
  49. package/dist/stream-idle-guard.js +75 -0
  50. package/dist/tool-execution-observation.js +141 -0
  51. package/dist/uuidv7.js +21 -0
  52. package/dist/work-subject-identity.js +53 -0
  53. package/extensions/role-runtime.ts +303 -0
  54. package/package.json +69 -0
  55. package/packets/fixer-prerequisites.json +6 -0
  56. package/packets/fixer-repair.md +5 -0
  57. package/packets/judge-apply.md +77 -0
  58. package/packets/judge-authority.md +64 -0
  59. package/packets/judge-plan.md +55 -0
  60. package/packets/judge-review.md +49 -0
  61. package/packets/judge-submission.md +34 -0
  62. package/resources/methods/code-review/SKILL.md +92 -0
  63. package/resources/methods/code-review/agents/openai.yaml +3 -0
  64. package/resources/methods/code-review/provenance.json +26 -0
  65. package/resources/methods/diagnosing-bugs/SKILL.md +134 -0
  66. package/resources/methods/diagnosing-bugs/agents/openai.yaml +3 -0
  67. package/resources/methods/diagnosing-bugs/provenance.json +31 -0
  68. package/resources/methods/diagnosing-bugs/scripts/hitl-loop.template.sh +41 -0
  69. package/resources/methods/resolving-merge-conflicts/SKILL.md +14 -0
  70. package/resources/methods/resolving-merge-conflicts/agents/openai.yaml +3 -0
  71. package/resources/methods/resolving-merge-conflicts/provenance.json +26 -0
  72. package/resources/methods/tdd/SKILL.md +38 -0
  73. package/resources/methods/tdd/agents/openai.yaml +3 -0
  74. package/resources/methods/tdd/mocking.md +59 -0
  75. package/resources/methods/tdd/provenance.json +36 -0
  76. package/resources/methods/tdd/tests.md +77 -0
  77. package/resources/navigator-route-playbook.md +32 -0
  78. package/schemas/tool-execution-observation.schema.json +107 -0
  79. package/scripts/build-package.mjs +65 -0
  80. package/scripts/generate-tool-execution-observation-schema.ts +7 -0
  81. package/souls/coder.md +10 -0
  82. package/souls/collector.md +11 -0
  83. package/souls/doctor-auditor.md +23 -0
  84. package/souls/doctor.md +8 -0
  85. package/souls/fixer-auditor.md +33 -0
  86. package/souls/fixer.md +13 -0
  87. package/souls/judge-auditor.md +33 -0
  88. package/souls/judge.md +74 -0
  89. package/souls/merger.md +5 -0
  90. package/souls/navigator.md +5 -0
  91. package/souls/reviewer-auditor.md +25 -0
  92. package/souls/reviewer.md +11 -0
  93. package/src/activation-ledger-git.ts +96 -0
  94. package/src/activation-ledger-session.ts +188 -0
  95. package/src/activation-ledger-topology.ts +301 -0
  96. package/src/activation-ledger.ts +240 -0
  97. package/src/activation-reconciliation.ts +163 -0
  98. package/src/activation-trace.ts +38 -0
  99. package/src/audit-escalation.ts +177 -0
  100. package/src/auditor-dossier-tool.ts +48 -0
  101. package/src/auditor-soul.ts +28 -0
  102. package/src/canonical-json.ts +74 -0
  103. package/src/canonical-skill-binding.ts +107 -0
  104. package/src/collector-config.ts +89 -0
  105. package/src/collector-evidence.ts +461 -0
  106. package/src/collector-github.ts +656 -0
  107. package/src/collector-identity.ts +161 -0
  108. package/src/collector-ledger.ts +827 -0
  109. package/src/collector-receipt.ts +87 -0
  110. package/src/collector-role.ts +592 -0
  111. package/src/collector-tool-schemas.ts +19 -0
  112. package/src/compliance-transport.ts +130 -0
  113. package/src/doctor-auditor.ts +53 -0
  114. package/src/doctor-contracts.ts +166 -0
  115. package/src/doctor-evidence.ts +47 -0
  116. package/src/doctor-role.ts +18 -0
  117. package/src/dossier-resolution.ts +137 -0
  118. package/src/evidence-child-executor.ts +775 -0
  119. package/src/exact-utf8.ts +9 -0
  120. package/src/factory-board.ts +1822 -0
  121. package/src/git-object-id.ts +11 -0
  122. package/src/human-format.ts +65 -0
  123. package/src/in-process-session.ts +78 -0
  124. package/src/judge-auditor.ts +55 -0
  125. package/src/judge-recording-anti-forge.ts +53 -0
  126. package/src/judge-role.ts +160 -0
  127. package/src/merger-contracts.ts +71 -0
  128. package/src/merger-git-state.ts +76 -0
  129. package/src/merger-role.ts +60 -0
  130. package/src/navigator-attendance.ts +1254 -0
  131. package/src/navigator-invocation-identity.ts +446 -0
  132. package/src/open-tool-schema.ts +46 -0
  133. package/src/package-contracts/collector-output.ts +109 -0
  134. package/src/package-contracts/fixer-output.ts +81 -0
  135. package/src/package-contracts/fixer-packet.ts +93 -0
  136. package/src/package-contracts/judge-output.ts +39 -0
  137. package/src/package-contracts/reviewer-output.ts +115 -0
  138. package/src/package-contracts/terminating-tools.ts +259 -0
  139. package/src/package-contracts/worker-output.ts +36 -0
  140. package/src/package-owned-tool-idle.ts +134 -0
  141. package/src/package-resources/method-skill-binding.ts +87 -0
  142. package/src/package-resources/method-skill.ts +358 -0
  143. package/src/packaged-role-registry.ts +36 -0
  144. package/src/public-cli/cli-errors.ts +11 -0
  145. package/src/public-cli/cli-io.ts +4 -0
  146. package/src/public-cli/cli.ts +912 -0
  147. package/src/public-cli/coder-run.ts +575 -0
  148. package/src/public-cli/collector-run.ts +375 -0
  149. package/src/public-cli/command-renderer.ts +8 -0
  150. package/src/public-cli/config.ts +346 -0
  151. package/src/public-cli/doctor-run.ts +355 -0
  152. package/src/public-cli/explicit-internal.ts +274 -0
  153. package/src/public-cli/fixer-run.ts +587 -0
  154. package/src/public-cli/host-pi-runtime.ts +112 -0
  155. package/src/public-cli/invocation.ts +1958 -0
  156. package/src/public-cli/judge-run.ts +507 -0
  157. package/src/public-cli/main.ts +15 -0
  158. package/src/public-cli/merger-run.ts +681 -0
  159. package/src/public-cli/public-run-credentials.ts +71 -0
  160. package/src/public-cli/registry.ts +153 -0
  161. package/src/public-cli/reviewer-run.ts +561 -0
  162. package/src/public-cli/run-lifecycle.ts +884 -0
  163. package/src/public-cli/settlement.ts +3765 -0
  164. package/src/public-cli/terminal.ts +325 -0
  165. package/src/public-command-renderer.ts +43 -0
  166. package/src/reviewer-agent.ts +94 -0
  167. package/src/reviewer-auditor.ts +53 -0
  168. package/src/reviewer-child-executor.ts +31 -0
  169. package/src/reviewer-construction.ts +137 -0
  170. package/src/reviewer-dispatch.ts +94 -0
  171. package/src/reviewer-execution-ledger.ts +206 -0
  172. package/src/reviewer-failure-diagnostic.ts +18 -0
  173. package/src/reviewer-git-snapshot.ts +53 -0
  174. package/src/reviewer-pinned-git.ts +144 -0
  175. package/src/reviewer-preflight-error.ts +14 -0
  176. package/src/reviewer-prompt-identity.ts +17 -0
  177. package/src/reviewer-role.ts +193 -0
  178. package/src/reviewer-scope-prompt.ts +24 -0
  179. package/src/reviewer-settlement.ts +63 -0
  180. package/src/reviewer-workspace.ts +111 -0
  181. package/src/role-runtime.ts +884 -0
  182. package/src/sha256.ts +6 -0
  183. package/src/sitian-record-entry.ts +57 -0
  184. package/src/stderr-jsonl.ts +28 -0
  185. package/src/stream-idle-guard.ts +98 -0
  186. package/src/ticket-snapshot.ts +662 -0
  187. package/src/ticket-trajectory.ts +1000 -0
  188. package/src/tool-execution-observation.ts +168 -0
  189. package/src/uuidv7.ts +1 -0
  190. package/src/work-subject-identity.ts +94 -0
  191. package/src/worker-role.ts +434 -0
  192. package/src/worker-submission-gates.ts +225 -0
@@ -0,0 +1,575 @@
1
+ /**
2
+ * Public Coder Role run: admit → explicit Internal activate → settle Terminal result.
3
+ * #109: package-owned TDD method, default apply / explicit plan, shared #106 success interface.
4
+ * Controlled-failure settlement reuses the #107 shared owner (no new failure classes).
5
+ */
6
+ import { writeFile } from "node:fs/promises";
7
+ import { join } from "node:path";
8
+
9
+ import {
10
+ loadPackagedMethodSkillMaterial,
11
+ resolvePackagedMethodSkillPath,
12
+ type PackagedMethodSkillProvenance,
13
+ } from "../package-resources/method-skill.ts";
14
+ import {
15
+ runExplicitInternalActivation,
16
+ type ExplicitInternalKnownFailure,
17
+ type ExplicitInternalPiRunner,
18
+ type ExplicitInternalPiResult,
19
+ } from "./explicit-internal.ts";
20
+ import { CliUsageError } from "./cli-errors.ts";
21
+ import {
22
+ admitCoderInvocation,
23
+ buildCoderTransportPrompt,
24
+ type AdmittedCoderInvocation,
25
+ } from "./invocation.ts";
26
+ import {
27
+ type CredentialProviders,
28
+ type SeatModelConfig,
29
+ } from "./config.ts";
30
+ import {
31
+ missingCredentialPreDispatchFailure,
32
+ postRunMissingCredentialFailure,
33
+ } from "./public-run-credentials.ts";
34
+ import {
35
+ acquireRunWriterLease,
36
+ clearTypedProviderHttpObservation,
37
+ isSessionPrincipalAvailable,
38
+ isV1ResumableFailure,
39
+ loadResumableCoderRun,
40
+ markRunAdmitted,
41
+ markRunResumable,
42
+ markRunRunning,
43
+ markRunTerminal,
44
+ readTypedHttp429Observation,
45
+ renderResumeCommand,
46
+ RESUME_TRANSPORT_ENVELOPE,
47
+ RunWriterLeaseHeldError,
48
+ type RunWriterLease,
49
+ } from "./run-lifecycle.ts";
50
+ import {
51
+ classifyPostAdmissionFailure,
52
+ exitCodeForTerminalOutcome,
53
+ formatCliDiagnostic,
54
+ formatTerminalResult,
55
+ hasLawfulCoderTerminalResult,
56
+ inspectJudgeSession,
57
+ isLawfulTypedTerminalOutcome,
58
+ presentFailureTerminal,
59
+ presentStructuralRejection,
60
+ explicitInternalKnownFailureClassificationInput,
61
+ resolveAuditedRunnerKnownFailure,
62
+ settleFailureTerminalResult,
63
+ trySettleCoderTerminalResult,
64
+ } from "./settlement.ts";
65
+ import type { CliIo } from "./cli-io.ts";
66
+ import type {
67
+ ControlledFailureCause,
68
+ TerminalResult,
69
+ } from "./terminal.ts";
70
+
71
+ export type CoderRunEnv = {
72
+ home: string;
73
+ agentDir: string;
74
+ packageRoot: string;
75
+ cwd: string;
76
+ correlationId?: string;
77
+ piRunner?: ExplicitInternalPiRunner;
78
+ model?: SeatModelConfig;
79
+ credentials?: CredentialProviders;
80
+ createRunId?: () => string;
81
+ extraPiArgs?: readonly string[];
82
+ timeoutMs?: number;
83
+ };
84
+
85
+ function buildModelArgs(model: SeatModelConfig | undefined): string[] {
86
+ if (model === undefined) return [];
87
+ return [
88
+ "--provider",
89
+ model.provider,
90
+ "--model",
91
+ model.model,
92
+ "--thinking",
93
+ model.thinking,
94
+ ];
95
+ }
96
+
97
+ /**
98
+ * Build Internal activation extra-args for an admitted Coder run.
99
+ * Apply phase pins the package-owned TDD Skill via --skill (no ambient home).
100
+ * Plan phase keeps --no-skills without a method Skill.
101
+ */
102
+ export function buildCoderActivationExtraArgs(
103
+ admitted: AdmittedCoderInvocation,
104
+ options: {
105
+ packageRoot: string;
106
+ model?: SeatModelConfig;
107
+ extraPiArgs?: readonly string[];
108
+ },
109
+ ): string[] {
110
+ const prompt = buildCoderTransportPrompt(admitted);
111
+ const skillArgs =
112
+ admitted.phase === "apply"
113
+ ? [
114
+ "--skill",
115
+ resolvePackagedMethodSkillPath(options.packageRoot, "tdd"),
116
+ ]
117
+ : [];
118
+ return [
119
+ "--no-skills",
120
+ ...skillArgs,
121
+ "--no-prompt-templates",
122
+ "--no-themes",
123
+ "--no-context-files",
124
+ "--session",
125
+ admitted.sessionFile,
126
+ "--session-dir",
127
+ admitted.sessionDirectory,
128
+ ...(options.extraPiArgs ?? []),
129
+ "--ak-role",
130
+ "coder",
131
+ "--ak-coder-phase",
132
+ admitted.phase,
133
+ "--ak-coder-task",
134
+ admitted.taskPath,
135
+ "--mode",
136
+ "json",
137
+ ...buildModelArgs(options.model),
138
+ prompt,
139
+ ];
140
+ }
141
+
142
+ /**
143
+ * Reopen the exact Coder Pi session for resume. Preserves admitted phase and
144
+ * package TDD binding; does not resubmit the original instruction.
145
+ */
146
+ export function buildCoderResumeActivationExtraArgs(
147
+ admitted: AdmittedCoderInvocation,
148
+ options: {
149
+ packageRoot: string;
150
+ model?: SeatModelConfig;
151
+ extraPiArgs?: readonly string[];
152
+ },
153
+ ): string[] {
154
+ const skillArgs =
155
+ admitted.phase === "apply"
156
+ ? [
157
+ "--skill",
158
+ resolvePackagedMethodSkillPath(options.packageRoot, "tdd"),
159
+ ]
160
+ : [];
161
+ return [
162
+ "--no-skills",
163
+ ...skillArgs,
164
+ "--no-prompt-templates",
165
+ "--no-themes",
166
+ "--no-context-files",
167
+ "--session",
168
+ admitted.sessionFile,
169
+ "--session-dir",
170
+ admitted.sessionDirectory,
171
+ ...(options.extraPiArgs ?? []),
172
+ "--ak-role",
173
+ "coder",
174
+ "--ak-coder-phase",
175
+ admitted.phase,
176
+ "--ak-coder-task",
177
+ admitted.taskPath,
178
+ "--mode",
179
+ "json",
180
+ ...buildModelArgs(options.model),
181
+ RESUME_TRANSPORT_ENVELOPE,
182
+ ];
183
+ }
184
+
185
+ async function presentControlledFailure(
186
+ admitted: AdmittedCoderInvocation,
187
+ failureInput: {
188
+ timedOut: boolean;
189
+ code: number | null;
190
+ stderr: string;
191
+ thrown?: unknown;
192
+ knownFailure?: ExplicitInternalKnownFailure;
193
+ knownCause?: ControlledFailureCause;
194
+ knownIdentity?: {
195
+ readonly name?: string;
196
+ readonly code?: string | number;
197
+ };
198
+ knownDiagnostic?: string;
199
+ },
200
+ io: CliIo,
201
+ ): Promise<{
202
+ exitCode: number;
203
+ admitted: AdmittedCoderInvocation;
204
+ terminal: TerminalResult;
205
+ }> {
206
+ const hasThrown = Object.hasOwn(failureInput, "thrown");
207
+ const session =
208
+ !hasThrown &&
209
+ !failureInput.timedOut &&
210
+ failureInput.knownFailure === undefined &&
211
+ failureInput.knownCause === undefined
212
+ ? await inspectJudgeSession(admitted.sessionFile)
213
+ : undefined;
214
+ const failure = classifyPostAdmissionFailure({
215
+ timedOut: failureInput.timedOut,
216
+ code: failureInput.code,
217
+ stderr: failureInput.stderr,
218
+ ...(hasThrown ? { thrown: failureInput.thrown } : {}),
219
+ ...explicitInternalKnownFailureClassificationInput(failureInput.knownFailure),
220
+ ...(failureInput.knownCause === undefined
221
+ ? {}
222
+ : { knownCause: failureInput.knownCause }),
223
+ ...(failureInput.knownIdentity === undefined
224
+ ? {}
225
+ : { knownIdentity: failureInput.knownIdentity }),
226
+ ...(failureInput.knownDiagnostic === undefined
227
+ ? {}
228
+ : { knownDiagnostic: failureInput.knownDiagnostic }),
229
+ ...(session === undefined ? {} : { session }),
230
+ });
231
+
232
+ const hasLawfulTerminalResult = await hasLawfulCoderTerminalResult(admitted);
233
+ const typedHttp429 = await readTypedHttp429Observation(admitted.runDirectory);
234
+ const sessionPrincipalAvailable = await isSessionPrincipalAvailable(
235
+ admitted.sessionFile,
236
+ );
237
+ const resumable =
238
+ sessionPrincipalAvailable &&
239
+ isV1ResumableFailure({
240
+ hasLawfulTerminalResult,
241
+ ...(typedHttp429 === undefined ? {} : { typedHttp429 }),
242
+ });
243
+ if (resumable && typedHttp429 !== undefined) {
244
+ await markRunResumable(admitted.runDirectory, typedHttp429);
245
+ } else {
246
+ await markRunTerminal(admitted.runDirectory).catch(() => undefined);
247
+ }
248
+
249
+ // #107 owns generic controlled-failure settlement — consume, do not re-own.
250
+ const terminal = await settleFailureTerminalResult(
251
+ admitted,
252
+ failure,
253
+ resumable
254
+ ? { resume: { command: renderResumeCommand(admitted.runId) } }
255
+ : {},
256
+ );
257
+ presentFailureTerminal(terminal, io);
258
+ return {
259
+ exitCode: exitCodeForTerminalOutcome(terminal.roleOutcome),
260
+ admitted,
261
+ terminal,
262
+ };
263
+ }
264
+
265
+ async function dispatchAdmittedCoder(input: {
266
+ admitted: AdmittedCoderInvocation;
267
+ env: CoderRunEnv;
268
+ io: CliIo;
269
+ extraArgs: string[];
270
+ lease: RunWriterLease;
271
+ methodProvenance?: PackagedMethodSkillProvenance;
272
+ }): Promise<{
273
+ exitCode: number;
274
+ admitted: AdmittedCoderInvocation;
275
+ terminal?: TerminalResult;
276
+ }> {
277
+ const { admitted, env, io, extraArgs, lease, methodProvenance } = input;
278
+ try {
279
+ const missingCredential = missingCredentialPreDispatchFailure(
280
+ env.model,
281
+ env.credentials,
282
+ );
283
+ if (missingCredential !== undefined) {
284
+ return await presentControlledFailure(
285
+ admitted,
286
+ missingCredential,
287
+ io,
288
+ );
289
+ }
290
+ await markRunRunning(admitted.runDirectory);
291
+ await clearTypedProviderHttpObservation(admitted.runDirectory);
292
+
293
+ const childEnv: NodeJS.ProcessEnv = {
294
+ ...process.env,
295
+ HOME: env.home,
296
+ PI_CODING_AGENT_DIR: env.agentDir,
297
+ AK_ROLE_RUN_DIR: admitted.runDirectory,
298
+ };
299
+ if (env.correlationId !== undefined && env.correlationId.trim() !== "") {
300
+ childEnv.AK_CORRELATION_ID = env.correlationId;
301
+ }
302
+
303
+ let result: ExplicitInternalPiResult;
304
+ try {
305
+ result = await runExplicitInternalActivation({
306
+ packageRoot: env.packageRoot,
307
+ extraArgs,
308
+ cwd: admitted.projectRoot,
309
+ home: env.home,
310
+ agentDir: env.agentDir,
311
+ env: childEnv,
312
+ timeoutMs: env.timeoutMs,
313
+ ...(env.piRunner === undefined ? {} : { runner: env.piRunner }),
314
+ });
315
+ } catch (error) {
316
+ return await presentControlledFailure(
317
+ admitted,
318
+ {
319
+ timedOut: false,
320
+ code: null,
321
+ stderr: "",
322
+ thrown: error,
323
+ },
324
+ io,
325
+ );
326
+ }
327
+
328
+ try {
329
+ await writeFile(
330
+ join(admitted.runDirectory, "stderr.log"),
331
+ result.stderr,
332
+ "utf8",
333
+ );
334
+ } catch {
335
+ // continue to lawful / controlled-failure settlement
336
+ }
337
+
338
+ let lawful: TerminalResult | undefined;
339
+ try {
340
+ lawful = await trySettleCoderTerminalResult(admitted, {
341
+ ...(methodProvenance === undefined
342
+ ? {}
343
+ : { methodProvenance }),
344
+ });
345
+ } catch (error) {
346
+ return await presentControlledFailure(
347
+ admitted,
348
+ {
349
+ timedOut: false,
350
+ code: result.code,
351
+ stderr: result.stderr,
352
+ thrown: error,
353
+ },
354
+ io,
355
+ );
356
+ }
357
+ if (lawful !== undefined && isLawfulTypedTerminalOutcome(lawful.roleOutcome)) {
358
+ await markRunTerminal(admitted.runDirectory).catch(() => undefined);
359
+ io.stdout(formatTerminalResult(lawful));
360
+ return {
361
+ exitCode: exitCodeForTerminalOutcome(lawful.roleOutcome),
362
+ admitted,
363
+ terminal: lawful,
364
+ };
365
+ }
366
+
367
+ const credentialFailure = postRunMissingCredentialFailure(
368
+ result,
369
+ env.model,
370
+ env.credentials,
371
+ );
372
+ const knownFailure = await resolveAuditedRunnerKnownFailure({
373
+ runner: result.knownFailure,
374
+ sessionFile: admitted.sessionFile,
375
+ credential: credentialFailure,
376
+ });
377
+ return await presentControlledFailure(
378
+ admitted,
379
+ {
380
+ timedOut: result.timedOut,
381
+ code: result.code,
382
+ stderr: result.stderr,
383
+ ...(knownFailure === undefined ? {} : { knownFailure }),
384
+ },
385
+ io,
386
+ );
387
+ } finally {
388
+ await lease.release();
389
+ }
390
+ }
391
+
392
+ export async function runPublicCoder(
393
+ argv: readonly string[],
394
+ env: CoderRunEnv,
395
+ io: CliIo,
396
+ parseCoderArgv: (args: readonly string[]) => {
397
+ phase: "plan" | "apply";
398
+ instruction: string;
399
+ attachmentPaths: string[];
400
+ project?: string;
401
+ },
402
+ ): Promise<{
403
+ exitCode: number;
404
+ admitted?: AdmittedCoderInvocation;
405
+ terminal?: TerminalResult;
406
+ }> {
407
+ let admitted: AdmittedCoderInvocation;
408
+ try {
409
+ const parsed = parseCoderArgv(argv);
410
+ admitted = await admitCoderInvocation({
411
+ home: env.home,
412
+ cwd: env.cwd,
413
+ phase: parsed.phase,
414
+ instruction: parsed.instruction,
415
+ attachmentPaths: parsed.attachmentPaths,
416
+ ...(parsed.project === undefined ? {} : { project: parsed.project }),
417
+ ...(env.createRunId === undefined ? {} : { createRunId: env.createRunId }),
418
+ });
419
+ } catch (error) {
420
+ if (error instanceof CliUsageError) {
421
+ presentStructuralRejection(error, io);
422
+ return { exitCode: 2 };
423
+ }
424
+ throw error;
425
+ }
426
+
427
+ await markRunAdmitted(admitted);
428
+
429
+ let lease: RunWriterLease;
430
+ try {
431
+ lease = await acquireRunWriterLease(admitted.runDirectory);
432
+ } catch (error) {
433
+ if (error instanceof RunWriterLeaseHeldError) {
434
+ presentStructuralRejection(error, io);
435
+ return { exitCode: 2 };
436
+ }
437
+ throw error;
438
+ }
439
+
440
+ let methodProvenance: PackagedMethodSkillProvenance | undefined;
441
+ if (admitted.phase === "apply") {
442
+ try {
443
+ const material = await loadPackagedMethodSkillMaterial(
444
+ env.packageRoot,
445
+ "tdd",
446
+ );
447
+ methodProvenance = material.provenance;
448
+ } catch (error) {
449
+ await lease.release();
450
+ return await presentControlledFailure(
451
+ admitted,
452
+ {
453
+ timedOut: false,
454
+ code: null,
455
+ stderr: "",
456
+ thrown: error,
457
+ knownCause: "activation",
458
+ },
459
+ io,
460
+ );
461
+ }
462
+ }
463
+
464
+ const extraArgs = buildCoderActivationExtraArgs(admitted, {
465
+ packageRoot: env.packageRoot,
466
+ ...(env.model === undefined ? {} : { model: env.model }),
467
+ ...(env.extraPiArgs === undefined ? {} : { extraPiArgs: env.extraPiArgs }),
468
+ });
469
+
470
+ return await dispatchAdmittedCoder({
471
+ admitted,
472
+ env,
473
+ io,
474
+ extraArgs,
475
+ lease,
476
+ ...(methodProvenance === undefined ? {} : { methodProvenance }),
477
+ });
478
+ }
479
+
480
+ /**
481
+ * Resume a previously admitted Coder Role run after a typed HTTP 429.
482
+ * Restores role/phase/task/session identity; model override is temporary.
483
+ */
484
+ export async function runPublicCoderResume(
485
+ argv: readonly string[],
486
+ env: CoderRunEnv,
487
+ io: CliIo,
488
+ ): Promise<{
489
+ exitCode: number;
490
+ admitted?: AdmittedCoderInvocation;
491
+ terminal?: TerminalResult;
492
+ }> {
493
+ const runId = argv[0];
494
+ if (runId === undefined || runId.trim() === "" || runId.startsWith("-")) {
495
+ presentStructuralRejection(
496
+ new CliUsageError("usage: ak-role resume <runId>"),
497
+ io,
498
+ );
499
+ return { exitCode: 2 };
500
+ }
501
+ if (argv.length > 1) {
502
+ presentStructuralRejection(
503
+ new CliUsageError("resume takes exactly one run id"),
504
+ io,
505
+ );
506
+ return { exitCode: 2 };
507
+ }
508
+
509
+ let loaded;
510
+ try {
511
+ loaded = await loadResumableCoderRun(env.home, runId);
512
+ } catch (error) {
513
+ if (error instanceof CliUsageError) {
514
+ presentStructuralRejection(error, io);
515
+ return { exitCode: 2 };
516
+ }
517
+ throw error;
518
+ }
519
+
520
+ const { admitted } = loaded;
521
+
522
+ let lease: RunWriterLease;
523
+ try {
524
+ lease = await acquireRunWriterLease(admitted.runDirectory);
525
+ } catch (error) {
526
+ if (error instanceof RunWriterLeaseHeldError) {
527
+ // Concurrent resume: reject without second writer or dispatch.
528
+ io.stderr(formatCliDiagnostic(error.message));
529
+ return { exitCode: 1 };
530
+ }
531
+ throw error;
532
+ }
533
+
534
+ let methodProvenance: PackagedMethodSkillProvenance | undefined;
535
+ if (admitted.phase === "apply") {
536
+ try {
537
+ const material = await loadPackagedMethodSkillMaterial(
538
+ env.packageRoot,
539
+ "tdd",
540
+ );
541
+ methodProvenance = material.provenance;
542
+ } catch (error) {
543
+ await lease.release();
544
+ return await presentControlledFailure(
545
+ admitted,
546
+ {
547
+ timedOut: false,
548
+ code: null,
549
+ stderr: "",
550
+ thrown: error,
551
+ knownCause: "activation",
552
+ },
553
+ io,
554
+ );
555
+ }
556
+ }
557
+
558
+ const extraArgs = buildCoderResumeActivationExtraArgs(admitted, {
559
+ packageRoot: env.packageRoot,
560
+ ...(env.model === undefined ? {} : { model: env.model }),
561
+ ...(env.extraPiArgs === undefined ? {} : { extraPiArgs: env.extraPiArgs }),
562
+ });
563
+
564
+ return await dispatchAdmittedCoder({
565
+ admitted,
566
+ env,
567
+ io,
568
+ extraArgs,
569
+ lease,
570
+ ...(methodProvenance === undefined ? {} : { methodProvenance }),
571
+ });
572
+ }
573
+
574
+ // Re-export for tests that assert typed credential failure channel shape.
575
+ export type { ExplicitInternalKnownFailure };