@akagilnc/pi-workflow-roles 0.1.1883 → 0.1.1893

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.
@@ -41,11 +41,11 @@ import {
41
41
  markRunResumable,
42
42
  markRunRunning,
43
43
  markRunTerminal,
44
- readTypedHttp429Observation,
45
44
  renderResumeCommand,
46
45
  RESUME_TRANSPORT_ENVELOPE,
47
46
  RunWriterLeaseHeldError,
48
47
  type RunWriterLease,
48
+ type TypedProviderHttpObservation,
49
49
  } from "./run-lifecycle.ts";
50
50
  import {
51
51
  classifyPostAdmissionFailure,
@@ -58,7 +58,9 @@ import {
58
58
  presentFailureTerminal,
59
59
  presentStructuralRejection,
60
60
  explicitInternalKnownFailureClassificationInput,
61
- resolveAuditedRunnerKnownFailure,
61
+ resolveAuditedRunnerFailureResolution,
62
+ resolveControlledFailureResumeObservation,
63
+ controlledFailureInputFromResolution,
62
64
  settleFailureTerminalResult,
63
65
  trySettleCoderTerminalResult,
64
66
  } from "./settlement.ts";
@@ -196,6 +198,8 @@ async function presentControlledFailure(
196
198
  readonly code?: string | number;
197
199
  };
198
200
  knownDiagnostic?: string;
201
+ typedHttpObservationSettled?: true;
202
+ typedHttpObservation?: TypedProviderHttpObservation;
199
203
  },
200
204
  io: CliIo,
201
205
  ): Promise<{
@@ -204,10 +208,23 @@ async function presentControlledFailure(
204
208
  terminal: TerminalResult;
205
209
  }> {
206
210
  const hasThrown = Object.hasOwn(failureInput, "thrown");
211
+ const resumeObservation = await resolveControlledFailureResumeObservation({
212
+ runDirectory: admitted.runDirectory,
213
+ ...(failureInput.typedHttpObservationSettled === true
214
+ ? {
215
+ typedHttpObservationSettled: true as const,
216
+ ...(failureInput.typedHttpObservation === undefined
217
+ ? {}
218
+ : { typedHttpObservation: failureInput.typedHttpObservation }),
219
+ }
220
+ : {}),
221
+ });
222
+ const knownFailure =
223
+ failureInput.knownFailure ?? resumeObservation.observationReadFailure;
207
224
  const session =
208
225
  !hasThrown &&
209
226
  !failureInput.timedOut &&
210
- failureInput.knownFailure === undefined &&
227
+ knownFailure === undefined &&
211
228
  failureInput.knownCause === undefined
212
229
  ? await inspectJudgeSession(admitted.sessionFile)
213
230
  : undefined;
@@ -216,7 +233,7 @@ async function presentControlledFailure(
216
233
  code: failureInput.code,
217
234
  stderr: failureInput.stderr,
218
235
  ...(hasThrown ? { thrown: failureInput.thrown } : {}),
219
- ...explicitInternalKnownFailureClassificationInput(failureInput.knownFailure),
236
+ ...explicitInternalKnownFailureClassificationInput(knownFailure),
220
237
  ...(failureInput.knownCause === undefined
221
238
  ? {}
222
239
  : { knownCause: failureInput.knownCause }),
@@ -230,7 +247,7 @@ async function presentControlledFailure(
230
247
  });
231
248
 
232
249
  const hasLawfulTerminalResult = await hasLawfulCoderTerminalResult(admitted);
233
- const typedHttp429 = await readTypedHttp429Observation(admitted.runDirectory);
250
+ const typedHttp429 = resumeObservation.typedHttp429;
234
251
  const sessionPrincipalAvailable = await isSessionPrincipalAvailable(
235
252
  admitted.sessionFile,
236
253
  );
@@ -369,10 +386,11 @@ async function dispatchAdmittedCoder(input: {
369
386
  env.model,
370
387
  env.credentials,
371
388
  );
372
- const knownFailure = await resolveAuditedRunnerKnownFailure({
389
+ const resolution = await resolveAuditedRunnerFailureResolution({
373
390
  runner: result.knownFailure,
374
391
  sessionFile: admitted.sessionFile,
375
392
  credential: credentialFailure,
393
+ runDirectory: admitted.runDirectory,
376
394
  });
377
395
  return await presentControlledFailure(
378
396
  admitted,
@@ -380,7 +398,7 @@ async function dispatchAdmittedCoder(input: {
380
398
  timedOut: result.timedOut,
381
399
  code: result.code,
382
400
  stderr: result.stderr,
383
- ...(knownFailure === undefined ? {} : { knownFailure }),
401
+ ...controlledFailureInputFromResolution(resolution),
384
402
  },
385
403
  io,
386
404
  );
@@ -299,6 +299,7 @@ async function dispatchAdmittedCollector(input: {
299
299
  }),
300
300
  sessionFile: admitted.sessionFile,
301
301
  credential: credentialFailure,
302
+ runDirectory: admitted.runDirectory,
302
303
  });
303
304
  return await presentControlledFailure(
304
305
  admitted,
@@ -280,6 +280,7 @@ async function dispatchAdmittedDoctor(input: {
280
280
  runner: result.knownFailure,
281
281
  sessionFile: admitted.sessionFile,
282
282
  credential: credentialFailure,
283
+ runDirectory: admitted.runDirectory,
283
284
  });
284
285
  return await presentControlledFailure(
285
286
  admitted,
@@ -21,6 +21,12 @@ import {
21
21
  type ReviewerPreflightViolation,
22
22
  } from "../reviewer-dispatch.ts";
23
23
  import type { ControlledFailureCause } from "./terminal.ts";
24
+ import {
25
+ hasUpstreamErrorTestimony,
26
+ projectConfirmedRemotePayload,
27
+ } from "../upstream-error-testimony.ts";
28
+
29
+ export { hasUpstreamErrorTestimony } from "../upstream-error-testimony.ts";
24
30
 
25
31
  /** Durable Reviewer-rejection child→parent page under AK_ROLE_RUN_DIR. */
26
32
  const REVIEWER_DISPATCH_REJECTION_FILE = "typed-known-failure.json";
@@ -147,34 +153,70 @@ export type ExplicitInternalKnownFailure = {
147
153
  readonly details?: Readonly<Record<string, unknown>>;
148
154
  };
149
155
 
156
+ function nonEmptyString(value: unknown): string | undefined {
157
+ return typeof value === "string" && value.trim() !== "" ? value : undefined;
158
+ }
159
+
160
+ function sessionStopDetails(input: {
161
+ readonly errorMessage?: string | null;
162
+ readonly provider?: string;
163
+ readonly model?: string;
164
+ readonly api?: string;
165
+ readonly rawStopReason?: string;
166
+ readonly httpStatus?: number;
167
+ readonly diagnostics?: unknown;
168
+ readonly body?: unknown;
169
+ readonly code?: unknown;
170
+ readonly errno?: unknown;
171
+ }): Record<string, unknown> {
172
+ const details: Record<string, unknown> = {};
173
+ const errorMessage = nonEmptyString(input.errorMessage);
174
+ if (errorMessage !== undefined) details.errorMessage = errorMessage;
175
+ const api = nonEmptyString(input.api);
176
+ if (api !== undefined) details.api = api;
177
+ const rawStopReason = nonEmptyString(input.rawStopReason);
178
+ if (rawStopReason !== undefined) details.rawStopReason = rawStopReason;
179
+ const testimony = hasUpstreamErrorTestimony(input);
180
+ if (testimony) {
181
+ const provider = nonEmptyString(input.provider);
182
+ if (provider !== undefined) details.provider = provider;
183
+ const model = nonEmptyString(input.model);
184
+ if (model !== undefined) details.model = model;
185
+ }
186
+ if (typeof input.httpStatus === "number") details.httpStatus = input.httpStatus;
187
+ if (input.diagnostics !== undefined) details.diagnostics = input.diagnostics;
188
+ // SDK structured payload fields: project only when held on a confirmed-remote node.
189
+ if (testimony) Object.assign(details, projectConfirmedRemotePayload(input));
190
+ return details;
191
+ }
192
+
150
193
  /**
151
- * Produce a typed provider knownFailure from a native session assistant stop.
152
- * Source fields are session-typed (stopReason / errorMessage / provider) — never
153
- * child stderr prose. Used by the public classifier after a real Pi child exits.
194
+ * Project a native session assistant stop onto the existing knownFailure chain.
195
+ * Classification follows two-way testimony: typed HTTP status or SDK structure
196
+ * keeps provider; stopReason, configured provider/model, or errorMessage prose
197
+ * alone is the existing unrecognized value. Present upstream payload is preserved
198
+ * in details without rewriting; missing fields are omitted.
154
199
  */
155
200
  export function knownFailureFromProviderStop(input: {
156
201
  readonly stopReason?: string;
157
202
  readonly errorMessage?: string | null;
158
203
  readonly provider?: string;
159
204
  readonly model?: string;
205
+ readonly api?: string;
206
+ readonly rawStopReason?: string;
207
+ readonly httpStatus?: number;
208
+ readonly diagnostics?: unknown;
209
+ readonly body?: unknown;
210
+ readonly code?: unknown;
211
+ readonly errno?: unknown;
160
212
  }): ExplicitInternalKnownFailure | undefined {
161
- if (input.stopReason !== "error") return undefined;
162
- const diagnostic =
163
- typeof input.errorMessage === "string" && input.errorMessage.trim() !== ""
164
- ? input.errorMessage.trim()
165
- : "provider failure";
166
- const identity: { name: string; code?: string } = {
167
- name: "ProviderStopError",
168
- };
169
- if (typeof input.provider === "string" && input.provider.trim() !== "") {
170
- identity.code = input.provider;
171
- } else if (typeof input.model === "string" && input.model.trim() !== "") {
172
- identity.code = input.model;
173
- }
213
+ if (input.stopReason !== "error" && input.stopReason !== "aborted") return undefined;
214
+ const diagnostic = nonEmptyString(input.errorMessage);
215
+ const details = sessionStopDetails(input);
174
216
  return {
175
- cause: "provider",
176
- identity,
177
- diagnostic,
217
+ cause: hasUpstreamErrorTestimony(input) ? "provider" : "unrecognized",
218
+ ...(diagnostic === undefined ? {} : { diagnostic }),
219
+ ...(Object.keys(details).length === 0 ? {} : { details }),
178
220
  };
179
221
  }
180
222
 
@@ -47,7 +47,7 @@ import {
47
47
  RESUME_TRANSPORT_ENVELOPE,
48
48
  RunWriterLeaseHeldError,
49
49
  type RunWriterLease,
50
- readTypedHttp429Observation,
50
+ type TypedProviderHttpObservation,
51
51
  } from "./run-lifecycle.ts";
52
52
  import {
53
53
  classifyPostAdmissionFailure,
@@ -59,7 +59,9 @@ import {
59
59
  isLawfulTypedTerminalOutcome,
60
60
  presentFailureTerminal,
61
61
  presentStructuralRejection,
62
- resolveAuditedRunnerKnownFailure,
62
+ resolveAuditedRunnerFailureResolution,
63
+ resolveControlledFailureResumeObservation,
64
+ controlledFailureInputFromResolution,
63
65
  explicitInternalKnownFailureClassificationInput,
64
66
  settleFailureTerminalResult,
65
67
  trySettleFixerTerminalResult,
@@ -205,6 +207,8 @@ async function presentControlledFailure(
205
207
  stderr: string;
206
208
  thrown?: unknown;
207
209
  knownFailure?: ExplicitInternalKnownFailure;
210
+ typedHttpObservationSettled?: true;
211
+ typedHttpObservation?: TypedProviderHttpObservation;
208
212
  },
209
213
  io: CliIo,
210
214
  ): Promise<{
@@ -213,10 +217,23 @@ async function presentControlledFailure(
213
217
  terminal: TerminalResult;
214
218
  }> {
215
219
  const hasThrown = Object.hasOwn(failureInput, "thrown");
220
+ const resumeObservation = await resolveControlledFailureResumeObservation({
221
+ runDirectory: admitted.runDirectory,
222
+ ...(failureInput.typedHttpObservationSettled === true
223
+ ? {
224
+ typedHttpObservationSettled: true as const,
225
+ ...(failureInput.typedHttpObservation === undefined
226
+ ? {}
227
+ : { typedHttpObservation: failureInput.typedHttpObservation }),
228
+ }
229
+ : {}),
230
+ });
231
+ const knownFailure =
232
+ failureInput.knownFailure ?? resumeObservation.observationReadFailure;
216
233
  const session =
217
234
  !hasThrown &&
218
235
  !failureInput.timedOut &&
219
- failureInput.knownFailure === undefined
236
+ knownFailure === undefined
220
237
  ? await inspectJudgeSession(admitted.sessionFile)
221
238
  : undefined;
222
239
  const failure = classifyPostAdmissionFailure({
@@ -224,12 +241,12 @@ async function presentControlledFailure(
224
241
  code: failureInput.code,
225
242
  stderr: failureInput.stderr,
226
243
  ...(hasThrown ? { thrown: failureInput.thrown } : {}),
227
- ...explicitInternalKnownFailureClassificationInput(failureInput.knownFailure),
244
+ ...explicitInternalKnownFailureClassificationInput(knownFailure),
228
245
  ...(session === undefined ? {} : { session }),
229
246
  });
230
247
 
231
248
  const hasLawfulTerminalResult = await hasLawfulFixerTerminalResult(admitted);
232
- const typedHttp429 = await readTypedHttp429Observation(admitted.runDirectory);
249
+ const typedHttp429 = resumeObservation.typedHttp429;
233
250
  const sessionPrincipalAvailable = await isSessionPrincipalAvailable(
234
251
  admitted.sessionFile,
235
252
  );
@@ -386,10 +403,11 @@ async function dispatchAdmittedFixer(input: {
386
403
  env.model,
387
404
  env.credentials,
388
405
  );
389
- const knownFailure = await resolveAuditedRunnerKnownFailure({
406
+ const resolution = await resolveAuditedRunnerFailureResolution({
390
407
  runner: result.knownFailure,
391
408
  sessionFile: admitted.sessionFile,
392
409
  credential: credentialFailure,
410
+ runDirectory: admitted.runDirectory,
393
411
  });
394
412
  return await presentControlledFailure(
395
413
  admitted,
@@ -397,7 +415,7 @@ async function dispatchAdmittedFixer(input: {
397
415
  timedOut: result.timedOut,
398
416
  code: result.code,
399
417
  stderr: result.stderr,
400
- ...(knownFailure === undefined ? {} : { knownFailure }),
418
+ ...controlledFailureInputFromResolution(resolution),
401
419
  },
402
420
  io,
403
421
  );
@@ -36,8 +36,8 @@ import {
36
36
  markRunResumable,
37
37
  markRunRunning,
38
38
  markRunTerminal,
39
- readTypedHttp429Observation,
40
39
  renderResumeCommand,
40
+ type TypedProviderHttpObservation,
41
41
  RESUME_TRANSPORT_ENVELOPE,
42
42
  RunWriterLeaseHeldError,
43
43
  type RunWriterLease,
@@ -52,7 +52,9 @@ import {
52
52
  isLawfulTypedTerminalOutcome,
53
53
  presentFailureTerminal,
54
54
  presentStructuralRejection,
55
- resolveAuditedRunnerKnownFailure,
55
+ resolveAuditedRunnerFailureResolution,
56
+ resolveControlledFailureResumeObservation,
57
+ controlledFailureInputFromResolution,
56
58
  explicitInternalKnownFailureClassificationInput,
57
59
  settleJudgeFailureTerminalResult,
58
60
  trySettleJudgeTerminalResult,
@@ -171,6 +173,9 @@ async function presentControlledFailure(
171
173
  stderr: string;
172
174
  thrown?: unknown;
173
175
  knownFailure?: ExplicitInternalKnownFailure;
176
+ /** Pre-resolved typed-HTTP outcome — no second sidecar read when settled. */
177
+ typedHttpObservationSettled?: true;
178
+ typedHttpObservation?: TypedProviderHttpObservation;
174
179
  },
175
180
  io: CliIo,
176
181
  ): Promise<{
@@ -180,10 +185,25 @@ async function presentControlledFailure(
180
185
  }> {
181
186
  // Own-key presence, not value: `throw undefined` must not look like "no throw".
182
187
  const hasThrown = Object.hasOwn(failureInput, "thrown");
188
+ // v1 resume observation: reuse audited resolution when present; otherwise one
189
+ // controlled read. Non-absence failures fold into knownFailure — never escape.
190
+ const resumeObservation = await resolveControlledFailureResumeObservation({
191
+ runDirectory: admitted.runDirectory,
192
+ ...(failureInput.typedHttpObservationSettled === true
193
+ ? {
194
+ typedHttpObservationSettled: true as const,
195
+ ...(failureInput.typedHttpObservation === undefined
196
+ ? {}
197
+ : { typedHttpObservation: failureInput.typedHttpObservation }),
198
+ }
199
+ : {}),
200
+ });
201
+ const knownFailure =
202
+ failureInput.knownFailure ?? resumeObservation.observationReadFailure;
183
203
  const session =
184
204
  !hasThrown &&
185
205
  !failureInput.timedOut &&
186
- failureInput.knownFailure === undefined
206
+ knownFailure === undefined
187
207
  ? await inspectJudgeSession(admitted.sessionFile)
188
208
  : undefined;
189
209
  const failure = classifyPostAdmissionFailure({
@@ -191,7 +211,7 @@ async function presentControlledFailure(
191
211
  code: failureInput.code,
192
212
  stderr: failureInput.stderr,
193
213
  ...(hasThrown ? { thrown: failureInput.thrown } : {}),
194
- ...explicitInternalKnownFailureClassificationInput(failureInput.knownFailure),
214
+ ...explicitInternalKnownFailureClassificationInput(knownFailure),
195
215
  ...(session === undefined ? {} : { session }),
196
216
  });
197
217
 
@@ -199,7 +219,7 @@ async function presentControlledFailure(
199
219
  // absence of a lawful Judge result, and a durable exact Pi session principal.
200
220
  // Lawful presence is session-owned and must not depend on artifact publication.
201
221
  const hasLawfulTerminalResult = await hasLawfulJudgeTerminalResult(admitted);
202
- const typedHttp429 = await readTypedHttp429Observation(admitted.runDirectory);
222
+ const typedHttp429 = resumeObservation.typedHttp429;
203
223
  const sessionPrincipalAvailable = await isSessionPrincipalAvailable(
204
224
  admitted.sessionFile,
205
225
  );
@@ -355,10 +375,11 @@ async function dispatchAdmittedJudge(input: {
355
375
  env.model,
356
376
  env.credentials,
357
377
  );
358
- const knownFailure = await resolveAuditedRunnerKnownFailure({
378
+ const resolution = await resolveAuditedRunnerFailureResolution({
359
379
  runner: result.knownFailure,
360
380
  sessionFile: admitted.sessionFile,
361
381
  credential: credentialFailure,
382
+ runDirectory: admitted.runDirectory,
362
383
  });
363
384
  return await presentControlledFailure(
364
385
  admitted,
@@ -366,7 +387,7 @@ async function dispatchAdmittedJudge(input: {
366
387
  timedOut: result.timedOut,
367
388
  code: result.code,
368
389
  stderr: result.stderr,
369
- ...(knownFailure === undefined ? {} : { knownFailure }),
390
+ ...controlledFailureInputFromResolution(resolution),
370
391
  },
371
392
  io,
372
393
  );
@@ -50,7 +50,7 @@ import {
50
50
  RESUME_TRANSPORT_ENVELOPE,
51
51
  RunWriterLeaseHeldError,
52
52
  type RunWriterLease,
53
- readTypedHttp429Observation,
53
+ type TypedProviderHttpObservation,
54
54
  } from "./run-lifecycle.ts";
55
55
  import {
56
56
  classifyPostAdmissionFailure,
@@ -62,7 +62,9 @@ import {
62
62
  presentFailureTerminal,
63
63
  presentStructuralRejection,
64
64
  explicitInternalKnownFailureClassificationInput,
65
- resolveAuditedRunnerKnownFailure,
65
+ resolveAuditedRunnerFailureResolution,
66
+ resolveControlledFailureResumeObservation,
67
+ controlledFailureInputFromResolution,
66
68
  settleFailureTerminalResult,
67
69
  trySettleMergerTerminalResult,
68
70
  } from "./settlement.ts";
@@ -192,6 +194,8 @@ async function presentControlledFailure(
192
194
  readonly code?: string | number;
193
195
  };
194
196
  knownDiagnostic?: string;
197
+ typedHttpObservationSettled?: true;
198
+ typedHttpObservation?: TypedProviderHttpObservation;
195
199
  },
196
200
  io: CliIo,
197
201
  ): Promise<{
@@ -200,10 +204,23 @@ async function presentControlledFailure(
200
204
  terminal: TerminalResult;
201
205
  }> {
202
206
  const hasThrown = Object.hasOwn(failureInput, "thrown");
207
+ const resumeObservation = await resolveControlledFailureResumeObservation({
208
+ runDirectory: admitted.runDirectory,
209
+ ...(failureInput.typedHttpObservationSettled === true
210
+ ? {
211
+ typedHttpObservationSettled: true as const,
212
+ ...(failureInput.typedHttpObservation === undefined
213
+ ? {}
214
+ : { typedHttpObservation: failureInput.typedHttpObservation }),
215
+ }
216
+ : {}),
217
+ });
218
+ const knownFailure =
219
+ failureInput.knownFailure ?? resumeObservation.observationReadFailure;
203
220
  const session =
204
221
  !hasThrown &&
205
222
  !failureInput.timedOut &&
206
- failureInput.knownFailure === undefined &&
223
+ knownFailure === undefined &&
207
224
  failureInput.knownCause === undefined
208
225
  ? await inspectJudgeSession(admitted.sessionFile)
209
226
  : undefined;
@@ -212,7 +229,7 @@ async function presentControlledFailure(
212
229
  code: failureInput.code,
213
230
  stderr: failureInput.stderr,
214
231
  ...(hasThrown ? { thrown: failureInput.thrown } : {}),
215
- ...explicitInternalKnownFailureClassificationInput(failureInput.knownFailure),
232
+ ...explicitInternalKnownFailureClassificationInput(knownFailure),
216
233
  ...(failureInput.knownCause === undefined
217
234
  ? {}
218
235
  : { knownCause: failureInput.knownCause }),
@@ -226,7 +243,7 @@ async function presentControlledFailure(
226
243
  });
227
244
 
228
245
  const hasLawfulTerminalResult = await hasLawfulMergerTerminalResult(admitted);
229
- const typedHttp429 = await readTypedHttp429Observation(admitted.runDirectory);
246
+ const typedHttp429 = resumeObservation.typedHttp429;
230
247
  const sessionPrincipalAvailable = await isSessionPrincipalAvailable(
231
248
  admitted.sessionFile,
232
249
  );
@@ -367,10 +384,11 @@ async function dispatchAdmittedMerger(input: {
367
384
  env.model,
368
385
  env.credentials,
369
386
  );
370
- const knownFailure = await resolveAuditedRunnerKnownFailure({
387
+ const resolution = await resolveAuditedRunnerFailureResolution({
371
388
  runner: result.knownFailure,
372
389
  sessionFile: admitted.sessionFile,
373
390
  credential: credentialFailure,
391
+ runDirectory: admitted.runDirectory,
374
392
  });
375
393
  return await presentControlledFailure(
376
394
  admitted,
@@ -378,7 +396,7 @@ async function dispatchAdmittedMerger(input: {
378
396
  timedOut: result.timedOut,
379
397
  code: result.code,
380
398
  stderr: result.stderr,
381
- ...(knownFailure === undefined ? {} : { knownFailure }),
399
+ ...controlledFailureInputFromResolution(resolution),
382
400
  },
383
401
  io,
384
402
  );
@@ -44,11 +44,11 @@ import {
44
44
  markRunResumable,
45
45
  markRunRunning,
46
46
  markRunTerminal,
47
- readTypedHttp429Observation,
48
47
  renderResumeCommand,
49
48
  RESUME_TRANSPORT_ENVELOPE,
50
49
  RunWriterLeaseHeldError,
51
50
  type RunWriterLease,
51
+ type TypedProviderHttpObservation,
52
52
  } from "./run-lifecycle.ts";
53
53
  import {
54
54
  classifyPostAdmissionFailure,
@@ -60,7 +60,9 @@ import {
60
60
  isLawfulTypedTerminalOutcome,
61
61
  presentFailureTerminal,
62
62
  presentStructuralRejection,
63
- resolveAuditedRunnerKnownFailure,
63
+ resolveAuditedRunnerFailureResolution,
64
+ resolveControlledFailureResumeObservation,
65
+ controlledFailureInputFromResolution,
64
66
  explicitInternalKnownFailureClassificationInput,
65
67
  settleFailureTerminalResult,
66
68
  trySettleReviewerTerminalResult,
@@ -186,6 +188,8 @@ async function presentControlledFailure(
186
188
  stderr: string;
187
189
  thrown?: unknown;
188
190
  knownFailure?: ExplicitInternalKnownFailure;
191
+ typedHttpObservationSettled?: true;
192
+ typedHttpObservation?: TypedProviderHttpObservation;
189
193
  },
190
194
  io: CliIo,
191
195
  ): Promise<{
@@ -194,10 +198,23 @@ async function presentControlledFailure(
194
198
  terminal: TerminalResult;
195
199
  }> {
196
200
  const hasThrown = Object.hasOwn(failureInput, "thrown");
201
+ const resumeObservation = await resolveControlledFailureResumeObservation({
202
+ runDirectory: admitted.runDirectory,
203
+ ...(failureInput.typedHttpObservationSettled === true
204
+ ? {
205
+ typedHttpObservationSettled: true as const,
206
+ ...(failureInput.typedHttpObservation === undefined
207
+ ? {}
208
+ : { typedHttpObservation: failureInput.typedHttpObservation }),
209
+ }
210
+ : {}),
211
+ });
212
+ const knownFailure =
213
+ failureInput.knownFailure ?? resumeObservation.observationReadFailure;
197
214
  const session =
198
215
  !hasThrown &&
199
216
  !failureInput.timedOut &&
200
- failureInput.knownFailure === undefined
217
+ knownFailure === undefined
201
218
  ? await inspectJudgeSession(admitted.sessionFile)
202
219
  : undefined;
203
220
  const failure = classifyPostAdmissionFailure({
@@ -205,12 +222,12 @@ async function presentControlledFailure(
205
222
  code: failureInput.code,
206
223
  stderr: failureInput.stderr,
207
224
  ...(hasThrown ? { thrown: failureInput.thrown } : {}),
208
- ...explicitInternalKnownFailureClassificationInput(failureInput.knownFailure),
225
+ ...explicitInternalKnownFailureClassificationInput(knownFailure),
209
226
  ...(session === undefined ? {} : { session }),
210
227
  });
211
228
 
212
229
  const hasLawfulTerminalResult = await hasLawfulReviewerTerminalResult(admitted);
213
- const typedHttp429 = await readTypedHttp429Observation(admitted.runDirectory);
230
+ const typedHttp429 = resumeObservation.typedHttp429;
214
231
  const sessionPrincipalAvailable = await isSessionPrincipalAvailable(
215
232
  admitted.sessionFile,
216
233
  );
@@ -367,7 +384,7 @@ async function dispatchAdmittedReviewer(input: {
367
384
  env.model,
368
385
  env.credentials,
369
386
  );
370
- const knownFailure = await resolveAuditedRunnerKnownFailure({
387
+ const resolution = await resolveAuditedRunnerFailureResolution({
371
388
  runner: result.knownFailure,
372
389
  sessionFile: admitted.sessionFile,
373
390
  credential: credentialFailure,
@@ -379,7 +396,7 @@ async function dispatchAdmittedReviewer(input: {
379
396
  timedOut: result.timedOut,
380
397
  code: result.code,
381
398
  stderr: result.stderr,
382
- ...(knownFailure === undefined ? {} : { knownFailure }),
399
+ ...controlledFailureInputFromResolution(resolution),
383
400
  },
384
401
  io,
385
402
  );