@oneharness/sdk 0.9.0 → 0.10.0

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.
@@ -47,6 +47,17 @@ export type ControlReason = "unsupported" | "no_active_turn" | "not_running";
47
47
  * frame's `v` is what leaves room for `steer` later.
48
48
  */
49
49
  export type ControlVerb = "interrupt";
50
+ /**
51
+ * Why a candidate fell through — the closed set [`startup_failure_reason`]
52
+ * decides and [`crate::domain::report::FallThrough`] reports.
53
+ *
54
+ * A type rather than a token, because the set is closed and every reader
55
+ * downstream branches on it: a value no classifier produced cannot be built,
56
+ * and the JSON spelling below is the schema's rather than each call site's. A
57
+ * new variant is a report `schema_version` bump like any other enum value, since
58
+ * a consumer matching exhaustively learns of it only from the version.
59
+ */
60
+ export type FallThroughReason = "not-installed" | "spawn-error" | "auth" | "quota" | "session-not-found" | "untrusted-directory" | "input-too-large" | "model-not-found" | "rate-limit";
50
61
  export type ToolCallStatus = "completed" | "failed" | "timeout" | "interrupted";
51
62
  /**
52
63
  * How a normalized tool interval was obtained.
@@ -63,7 +74,7 @@ export type TimingSource = "provider_measured" | "stdout_observed";
63
74
  * the report, history) one definition to share instead of scattered string
64
75
  * literals.
65
76
  */
66
- export type FailureKind = "auth" | "rate_limit" | "model_not_found" | "quota" | "session_not_found" | "tool_deferred";
77
+ export type FailureKind = "auth" | "rate_limit" | "model_not_found" | "quota" | "session_not_found" | "tool_deferred" | "untrusted_directory" | "input_too_large";
67
78
  /**
68
79
  * How a harness emits its result, which decides how `text` is extracted.
69
80
  *
@@ -276,7 +287,8 @@ export interface FallbackReport {
276
287
  /**
277
288
  * The candidates fallen through because they could not run the task at all,
278
289
  * in priority order, each with why (`not-installed`, `spawn-error`, `auth`,
279
- * `quota`, and — on a model fan-out — `model-not-found` / `rate-limit`; see
290
+ * `quota`, `session-not-found`, `untrusted-directory`, `input-too-large`,
291
+ * and — on a model fan-out — `model-not-found` / `rate-limit`; see
280
292
  * [`crate::domain::fallback::startup_failure_reason`]).
281
293
  */
282
294
  fell_through: FallThrough[];
@@ -291,15 +303,29 @@ export interface FallbackReport {
291
303
  * One candidate a fallback run fell through, with the reason it could not run.
292
304
  */
293
305
  export interface FallThrough {
306
+ /**
307
+ * This candidate's own account of why it could not run: its
308
+ * [`RunResult::error`], copied — one value with one source, not a second
309
+ * rendering of it. `null` when the candidate said nothing beyond its status.
310
+ *
311
+ * So when the provider named the cause in machine-readable terms, what
312
+ * arrives here is the sentence naming the harness with that object **quoted
313
+ * inside it** (`… refused the request before running it:
314
+ * {"input_error_code":"input_too_large",…}`) — the object verbatim, not the
315
+ * object alone. A reader extracts it; nothing paraphrases it on the way.
316
+ *
317
+ * The `reason` above is oneharness's classification and stays a short,
318
+ * closed token; this is the cause underneath it, carried up so a supervisor
319
+ * reading only the fallback block never has to re-parse a fallen-through
320
+ * candidate's raw stdout to learn what the provider already said. Added in
321
+ * report schema `0.8`.
322
+ */
323
+ detail: string | null;
294
324
  /**
295
325
  * Canonical harness id.
296
326
  */
297
327
  harness: string;
298
- /**
299
- * Short reason token (`not-installed` / `spawn-error` / `auth` / `quota` /
300
- * `model-not-found` / `rate-limit`).
301
- */
302
- reason: string;
328
+ reason: FallThroughReason;
303
329
  [k: string]: unknown;
304
330
  }
305
331
  /**
@@ -6,7 +6,7 @@ export type HistoryLine = ({
6
6
  harness: string;
7
7
  harness_id?: string | null | undefined;
8
8
  run_id: string;
9
- schema_version: "1.2" | "1.3" | "1.4" | "1.5";
9
+ schema_version: "1.2" | "1.3" | "1.4" | "1.5" | "1.6";
10
10
  type: "event";
11
11
  variant?: string | null | undefined;
12
12
  [k: string]: unknown;
@@ -27,7 +27,7 @@ export type HistoryLine = ({
27
27
  [k: string]: unknown;
28
28
  } | ({
29
29
  error: string;
30
- schema_version?: "1.3" | "1.4" | "1.5" | undefined;
30
+ schema_version?: "1.3" | "1.4" | "1.5" | "1.6" | undefined;
31
31
  [k: string]: unknown;
32
32
  } & ({
33
33
  status?: "nonzero" | "timeout" | "cancelled" | "spawn-error" | "skipped" | undefined;
@@ -39,15 +39,21 @@ export type HistoryLine = ({
39
39
  status?: "ok" | "nonzero" | "timeout" | "spawn-error" | "skipped" | "planned" | undefined;
40
40
  [k: string]: unknown;
41
41
  } | {
42
- schema_version?: "1.4" | "1.5" | undefined;
42
+ schema_version?: "1.4" | "1.5" | "1.6" | undefined;
43
43
  [k: string]: unknown;
44
- }) & ({
45
- failure_kind?: "auth" | "rate_limit" | "model_not_found" | "quota" | "tool_deferred" | null | undefined;
44
+ }) & (({
45
+ failure_kind?: "auth" | "rate_limit" | "model_not_found" | "quota" | "tool_deferred" | "untrusted_directory" | "input_too_large" | null;
46
46
  [k: string]: unknown;
47
47
  } | {
48
- schema_version?: "1.5" | undefined;
48
+ schema_version?: "1.5" | "1.6" | undefined;
49
49
  [k: string]: unknown;
50
50
  }) & ({
51
+ failure_kind?: "auth" | "rate_limit" | "model_not_found" | "quota" | "session_not_found" | "tool_deferred" | null;
52
+ [k: string]: unknown;
53
+ } | {
54
+ schema_version?: "1.6" | undefined;
55
+ [k: string]: unknown;
56
+ })) & ({
51
57
  duration_ms: number;
52
58
  /**
53
59
  * Normalized failure text for a run that did not succeed (see
@@ -68,7 +74,7 @@ export type HistoryLine = ({
68
74
  permission_mode: PermissionMode;
69
75
  project: string;
70
76
  prompt: string;
71
- schema_version: "1.0" | "1.1" | "1.2" | "1.3" | "1.4" | "1.5";
77
+ schema_version: "1.0" | "1.1" | "1.2" | "1.3" | "1.4" | "1.5" | "1.6";
72
78
  session: string;
73
79
  session_id: string | null;
74
80
  started_at: string;
@@ -103,7 +109,7 @@ export type HistoryLine = ({
103
109
  permission_mode: PermissionMode;
104
110
  project: string;
105
111
  prompt: string;
106
- schema_version: "1.0" | "1.1" | "1.2" | "1.3" | "1.4" | "1.5";
112
+ schema_version: "1.0" | "1.1" | "1.2" | "1.3" | "1.4" | "1.5" | "1.6";
107
113
  session: string;
108
114
  session_id: string | null;
109
115
  started_at: string;
@@ -138,7 +144,7 @@ export type HistoryLine = ({
138
144
  permission_mode: PermissionMode;
139
145
  project: string;
140
146
  prompt: string;
141
- schema_version: "1.2" | "1.3" | "1.4" | "1.5";
147
+ schema_version: "1.2" | "1.3" | "1.4" | "1.5" | "1.6";
142
148
  session: string;
143
149
  session_id: string | null;
144
150
  started_at?: never | undefined;
@@ -173,7 +179,7 @@ export type HistoryLine = ({
173
179
  permission_mode: PermissionMode;
174
180
  project: string;
175
181
  prompt: string;
176
- schema_version: "1.0" | "1.1" | "1.2" | "1.3" | "1.4" | "1.5";
182
+ schema_version: "1.0" | "1.1" | "1.2" | "1.3" | "1.4" | "1.5" | "1.6";
177
183
  session: string;
178
184
  session_id: string | null;
179
185
  started_at?: never | undefined;
@@ -208,7 +214,7 @@ export type HistoryLine = ({
208
214
  permission_mode: PermissionMode;
209
215
  project: string;
210
216
  prompt: string;
211
- schema_version: "1.3" | "1.4" | "1.5";
217
+ schema_version: "1.3" | "1.4" | "1.5" | "1.6";
212
218
  session: string;
213
219
  session_id: string | null;
214
220
  started_at: string;
@@ -243,7 +249,7 @@ export type HistoryLine = ({
243
249
  permission_mode: PermissionMode;
244
250
  project: string;
245
251
  prompt: string;
246
- schema_version: "1.0" | "1.1" | "1.2" | "1.3" | "1.4" | "1.5";
252
+ schema_version: "1.0" | "1.1" | "1.2" | "1.3" | "1.4" | "1.5" | "1.6";
247
253
  session: string;
248
254
  session_id: string | null;
249
255
  started_at?: never | undefined;
@@ -274,7 +280,7 @@ export type TimingSource = "provider_measured" | "stdout_observed";
274
280
  * the report, history) one definition to share instead of scattered string
275
281
  * literals.
276
282
  */
277
- export type FailureKind = "auth" | "rate_limit" | "model_not_found" | "quota" | "session_not_found" | "tool_deferred";
283
+ export type FailureKind = "auth" | "rate_limit" | "model_not_found" | "quota" | "session_not_found" | "tool_deferred" | "untrusted_directory" | "input_too_large";
278
284
  /**
279
285
  * The unified approval mode, from least to most autonomy. A harness may not
280
286
  * support every value (see [`crate::domain::harness::HarnessSpec::mode`]); the
@@ -93,7 +93,7 @@ export type HistoryRecord = {
93
93
  * run's single prompt).
94
94
  */
95
95
  prompt: string;
96
- schema_version: "1.2" | "1.3" | "1.4" | "1.5";
96
+ schema_version: "1.2" | "1.3" | "1.4" | "1.5" | "1.6";
97
97
  /**
98
98
  * The oneharness session id this run belongs to (the history file's stem).
99
99
  */
@@ -323,7 +323,7 @@ export type HistoryRecord = {
323
323
  * run's single prompt).
324
324
  */
325
325
  prompt: string;
326
- schema_version: "1.2" | "1.3" | "1.4" | "1.5";
326
+ schema_version: "1.2" | "1.3" | "1.4" | "1.5" | "1.6";
327
327
  /**
328
328
  * The oneharness session id this run belongs to (the history file's stem).
329
329
  */
@@ -415,7 +415,7 @@ export type HistoryRecord = {
415
415
  * run's single prompt).
416
416
  */
417
417
  prompt: string;
418
- schema_version: "1.2" | "1.3" | "1.4" | "1.5";
418
+ schema_version: "1.2" | "1.3" | "1.4" | "1.5" | "1.6";
419
419
  /**
420
420
  * The oneharness session id this run belongs to (the history file's stem).
421
421
  */
@@ -507,7 +507,7 @@ export type HistoryRecord = {
507
507
  * run's single prompt).
508
508
  */
509
509
  prompt: string;
510
- schema_version: "1.2" | "1.3" | "1.4" | "1.5";
510
+ schema_version: "1.2" | "1.3" | "1.4" | "1.5" | "1.6";
511
511
  /**
512
512
  * The oneharness session id this run belongs to (the history file's stem).
513
513
  */
@@ -599,7 +599,7 @@ export type HistoryRecord = {
599
599
  * run's single prompt).
600
600
  */
601
601
  prompt: string;
602
- schema_version: "1.3" | "1.4" | "1.5";
602
+ schema_version: "1.3" | "1.4" | "1.5" | "1.6";
603
603
  /**
604
604
  * The oneharness session id this run belongs to (the history file's stem).
605
605
  */
@@ -951,7 +951,7 @@ export type TimingSource = "provider_measured" | "stdout_observed";
951
951
  * the report, history) one definition to share instead of scattered string
952
952
  * literals.
953
953
  */
954
- export type FailureKind = "auth" | "rate_limit" | "model_not_found" | "quota" | "session_not_found" | "tool_deferred";
954
+ export type FailureKind = "auth" | "rate_limit" | "model_not_found" | "quota" | "session_not_found" | "tool_deferred" | "untrusted_directory" | "input_too_large";
955
955
  /**
956
956
  * The outcome of attempting to run one harness.
957
957
  */
@@ -961,7 +961,7 @@ export type HistoryRecords = (({
961
961
  [k: string]: unknown;
962
962
  } | ({
963
963
  error: string;
964
- schema_version?: "1.3" | "1.4" | "1.5" | undefined;
964
+ schema_version?: "1.3" | "1.4" | "1.5" | "1.6" | undefined;
965
965
  [k: string]: unknown;
966
966
  } & ({
967
967
  status?: "nonzero" | "timeout" | "cancelled" | "spawn-error" | "skipped" | undefined;
@@ -973,15 +973,21 @@ export type HistoryRecords = (({
973
973
  status?: "ok" | "nonzero" | "timeout" | "spawn-error" | "skipped" | "planned" | undefined;
974
974
  [k: string]: unknown;
975
975
  } | {
976
- schema_version?: "1.4" | "1.5" | undefined;
976
+ schema_version?: "1.4" | "1.5" | "1.6" | undefined;
977
+ [k: string]: unknown;
978
+ }) & (({
979
+ failure_kind?: "auth" | "rate_limit" | "model_not_found" | "quota" | "tool_deferred" | "untrusted_directory" | "input_too_large" | null;
980
+ [k: string]: unknown;
981
+ } | {
982
+ schema_version?: "1.5" | "1.6" | undefined;
977
983
  [k: string]: unknown;
978
984
  }) & ({
979
- failure_kind?: "auth" | "rate_limit" | "model_not_found" | "quota" | "tool_deferred" | null | undefined;
985
+ failure_kind?: "auth" | "rate_limit" | "model_not_found" | "quota" | "session_not_found" | "tool_deferred" | null;
980
986
  [k: string]: unknown;
981
987
  } | {
982
- schema_version?: "1.5" | undefined;
988
+ schema_version?: "1.6" | undefined;
983
989
  [k: string]: unknown;
984
- }) & HistoryRecord)[];
990
+ })) & HistoryRecord)[];
985
991
  /**
986
992
  * One normalized action a harness took, harness-agnostic so a single consumer
987
993
  * assertion works across harnesses. Every field is always serialized (null when
@@ -14,7 +14,7 @@ export type HistoryStreamEnvelope = {
14
14
  [k: string]: unknown;
15
15
  } | ({
16
16
  error: string;
17
- schema_version?: "1.3" | "1.4" | "1.5" | undefined;
17
+ schema_version?: "1.3" | "1.4" | "1.5" | "1.6" | undefined;
18
18
  [k: string]: unknown;
19
19
  } & ({
20
20
  status?: "nonzero" | "timeout" | "cancelled" | "spawn-error" | "skipped" | undefined;
@@ -26,15 +26,21 @@ export type HistoryStreamEnvelope = {
26
26
  status?: "ok" | "nonzero" | "timeout" | "spawn-error" | "skipped" | "planned" | undefined;
27
27
  [k: string]: unknown;
28
28
  } | {
29
- schema_version?: "1.4" | "1.5" | undefined;
29
+ schema_version?: "1.4" | "1.5" | "1.6" | undefined;
30
+ [k: string]: unknown;
31
+ }) & (({
32
+ failure_kind?: "auth" | "rate_limit" | "model_not_found" | "quota" | "tool_deferred" | "untrusted_directory" | "input_too_large" | null;
33
+ [k: string]: unknown;
34
+ } | {
35
+ schema_version?: "1.5" | "1.6" | undefined;
30
36
  [k: string]: unknown;
31
37
  }) & ({
32
- failure_kind?: "auth" | "rate_limit" | "model_not_found" | "quota" | "tool_deferred" | null | undefined;
38
+ failure_kind?: "auth" | "rate_limit" | "model_not_found" | "quota" | "session_not_found" | "tool_deferred" | null;
33
39
  [k: string]: unknown;
34
40
  } | {
35
- schema_version?: "1.5" | undefined;
41
+ schema_version?: "1.6" | undefined;
36
42
  [k: string]: unknown;
37
- }) & HistoryRecord;
43
+ })) & HistoryRecord;
38
44
  type: "record";
39
45
  [k: string]: unknown;
40
46
  } | {
@@ -137,7 +143,7 @@ export type HistoryRecord = {
137
143
  * run's single prompt).
138
144
  */
139
145
  prompt: string;
140
- schema_version: "1.2" | "1.3" | "1.4" | "1.5";
146
+ schema_version: "1.2" | "1.3" | "1.4" | "1.5" | "1.6";
141
147
  /**
142
148
  * The oneharness session id this run belongs to (the history file's stem).
143
149
  */
@@ -367,7 +373,7 @@ export type HistoryRecord = {
367
373
  * run's single prompt).
368
374
  */
369
375
  prompt: string;
370
- schema_version: "1.2" | "1.3" | "1.4" | "1.5";
376
+ schema_version: "1.2" | "1.3" | "1.4" | "1.5" | "1.6";
371
377
  /**
372
378
  * The oneharness session id this run belongs to (the history file's stem).
373
379
  */
@@ -459,7 +465,7 @@ export type HistoryRecord = {
459
465
  * run's single prompt).
460
466
  */
461
467
  prompt: string;
462
- schema_version: "1.2" | "1.3" | "1.4" | "1.5";
468
+ schema_version: "1.2" | "1.3" | "1.4" | "1.5" | "1.6";
463
469
  /**
464
470
  * The oneharness session id this run belongs to (the history file's stem).
465
471
  */
@@ -551,7 +557,7 @@ export type HistoryRecord = {
551
557
  * run's single prompt).
552
558
  */
553
559
  prompt: string;
554
- schema_version: "1.2" | "1.3" | "1.4" | "1.5";
560
+ schema_version: "1.2" | "1.3" | "1.4" | "1.5" | "1.6";
555
561
  /**
556
562
  * The oneharness session id this run belongs to (the history file's stem).
557
563
  */
@@ -643,7 +649,7 @@ export type HistoryRecord = {
643
649
  * run's single prompt).
644
650
  */
645
651
  prompt: string;
646
- schema_version: "1.3" | "1.4" | "1.5";
652
+ schema_version: "1.3" | "1.4" | "1.5" | "1.6";
647
653
  /**
648
654
  * The oneharness session id this run belongs to (the history file's stem).
649
655
  */
@@ -995,7 +1001,7 @@ export type TimingSource = "provider_measured" | "stdout_observed";
995
1001
  * the report, history) one definition to share instead of scattered string
996
1002
  * literals.
997
1003
  */
998
- export type FailureKind = "auth" | "rate_limit" | "model_not_found" | "quota" | "session_not_found" | "tool_deferred";
1004
+ export type FailureKind = "auth" | "rate_limit" | "model_not_found" | "quota" | "session_not_found" | "tool_deferred" | "untrusted_directory" | "input_too_large";
999
1005
  /**
1000
1006
  * The outcome of attempting to run one harness.
1001
1007
  */
@@ -1005,7 +1011,7 @@ export type HistoryEventLine = {
1005
1011
  harness: string;
1006
1012
  harness_id?: string | null | undefined;
1007
1013
  run_id: string;
1008
- schema_version: "1.2" | "1.3" | "1.4" | "1.5";
1014
+ schema_version: "1.2" | "1.3" | "1.4" | "1.5" | "1.6";
1009
1015
  variant?: string | null | undefined;
1010
1016
  [k: string]: unknown;
1011
1017
  } | {
@@ -8,7 +8,7 @@ export type HistoryRecord = ({
8
8
  [k: string]: unknown;
9
9
  } | ({
10
10
  error: string;
11
- schema_version?: "1.3" | "1.4" | "1.5" | undefined;
11
+ schema_version?: "1.3" | "1.4" | "1.5" | "1.6" | undefined;
12
12
  [k: string]: unknown;
13
13
  } & ({
14
14
  status?: "nonzero" | "timeout" | "cancelled" | "spawn-error" | "skipped" | undefined;
@@ -20,15 +20,21 @@ export type HistoryRecord = ({
20
20
  status?: "ok" | "nonzero" | "timeout" | "spawn-error" | "skipped" | "planned" | undefined;
21
21
  [k: string]: unknown;
22
22
  } | {
23
- schema_version?: "1.4" | "1.5" | undefined;
23
+ schema_version?: "1.4" | "1.5" | "1.6" | undefined;
24
24
  [k: string]: unknown;
25
- }) & ({
26
- failure_kind?: "auth" | "rate_limit" | "model_not_found" | "quota" | "tool_deferred" | null | undefined;
25
+ }) & (({
26
+ failure_kind?: "auth" | "rate_limit" | "model_not_found" | "quota" | "tool_deferred" | "untrusted_directory" | "input_too_large" | null;
27
27
  [k: string]: unknown;
28
28
  } | {
29
- schema_version?: "1.5" | undefined;
29
+ schema_version?: "1.5" | "1.6" | undefined;
30
30
  [k: string]: unknown;
31
31
  }) & ({
32
+ failure_kind?: "auth" | "rate_limit" | "model_not_found" | "quota" | "session_not_found" | "tool_deferred" | null;
33
+ [k: string]: unknown;
34
+ } | {
35
+ schema_version?: "1.6" | undefined;
36
+ [k: string]: unknown;
37
+ })) & ({
32
38
  duration_ms: number;
33
39
  /**
34
40
  * Best-effort normalized failure text for a run that did not succeed: the
@@ -123,7 +129,7 @@ export type HistoryRecord = ({
123
129
  * run's single prompt).
124
130
  */
125
131
  prompt: string;
126
- schema_version: "1.2" | "1.3" | "1.4" | "1.5";
132
+ schema_version: "1.2" | "1.3" | "1.4" | "1.5" | "1.6";
127
133
  /**
128
134
  * The oneharness session id this run belongs to (the history file's stem).
129
135
  */
@@ -353,7 +359,7 @@ export type HistoryRecord = ({
353
359
  * run's single prompt).
354
360
  */
355
361
  prompt: string;
356
- schema_version: "1.2" | "1.3" | "1.4" | "1.5";
362
+ schema_version: "1.2" | "1.3" | "1.4" | "1.5" | "1.6";
357
363
  /**
358
364
  * The oneharness session id this run belongs to (the history file's stem).
359
365
  */
@@ -445,7 +451,7 @@ export type HistoryRecord = ({
445
451
  * run's single prompt).
446
452
  */
447
453
  prompt: string;
448
- schema_version: "1.2" | "1.3" | "1.4" | "1.5";
454
+ schema_version: "1.2" | "1.3" | "1.4" | "1.5" | "1.6";
449
455
  /**
450
456
  * The oneharness session id this run belongs to (the history file's stem).
451
457
  */
@@ -537,7 +543,7 @@ export type HistoryRecord = ({
537
543
  * run's single prompt).
538
544
  */
539
545
  prompt: string;
540
- schema_version: "1.2" | "1.3" | "1.4" | "1.5";
546
+ schema_version: "1.2" | "1.3" | "1.4" | "1.5" | "1.6";
541
547
  /**
542
548
  * The oneharness session id this run belongs to (the history file's stem).
543
549
  */
@@ -629,7 +635,7 @@ export type HistoryRecord = ({
629
635
  * run's single prompt).
630
636
  */
631
637
  prompt: string;
632
- schema_version: "1.3" | "1.4" | "1.5";
638
+ schema_version: "1.3" | "1.4" | "1.5" | "1.6";
633
639
  /**
634
640
  * The oneharness session id this run belongs to (the history file's stem).
635
641
  */
@@ -981,7 +987,7 @@ export type TimingSource = "provider_measured" | "stdout_observed";
981
987
  * the report, history) one definition to share instead of scattered string
982
988
  * literals.
983
989
  */
984
- export type FailureKind = "auth" | "rate_limit" | "model_not_found" | "quota" | "session_not_found" | "tool_deferred";
990
+ export type FailureKind = "auth" | "rate_limit" | "model_not_found" | "quota" | "session_not_found" | "tool_deferred" | "untrusted_directory" | "input_too_large";
985
991
  /**
986
992
  * The outcome of attempting to run one harness.
987
993
  */
@@ -69,6 +69,17 @@ export type ControlReason = "unsupported" | "no_active_turn" | "not_running";
69
69
  * frame's `v` is what leaves room for `steer` later.
70
70
  */
71
71
  export type ControlVerb = "interrupt";
72
+ /**
73
+ * Why a candidate fell through — the closed set [`startup_failure_reason`]
74
+ * decides and [`crate::domain::report::FallThrough`] reports.
75
+ *
76
+ * A type rather than a token, because the set is closed and every reader
77
+ * downstream branches on it: a value no classifier produced cannot be built,
78
+ * and the JSON spelling below is the schema's rather than each call site's. A
79
+ * new variant is a report `schema_version` bump like any other enum value, since
80
+ * a consumer matching exhaustively learns of it only from the version.
81
+ */
82
+ export type FallThroughReason = "not-installed" | "spawn-error" | "auth" | "quota" | "session-not-found" | "untrusted-directory" | "input-too-large" | "model-not-found" | "rate-limit";
72
83
  /**
73
84
  * The normalized, closed set of failure reasons oneharness can classify from a
74
85
  * harness's output. It is the single source for the `failure_kind` contract
@@ -80,7 +91,7 @@ export type ControlVerb = "interrupt";
80
91
  * the report, history) one definition to share instead of scattered string
81
92
  * literals.
82
93
  */
83
- export type FailureKind = "auth" | "rate_limit" | "model_not_found" | "quota" | "session_not_found" | "tool_deferred";
94
+ export type FailureKind = "auth" | "rate_limit" | "model_not_found" | "quota" | "session_not_found" | "tool_deferred" | "untrusted_directory" | "input_too_large";
84
95
  /**
85
96
  * How a harness emits its result, which decides how `text` is extracted.
86
97
  *
@@ -350,7 +361,8 @@ export interface FallbackReport {
350
361
  /**
351
362
  * The candidates fallen through because they could not run the task at all,
352
363
  * in priority order, each with why (`not-installed`, `spawn-error`, `auth`,
353
- * `quota`, and — on a model fan-out — `model-not-found` / `rate-limit`; see
364
+ * `quota`, `session-not-found`, `untrusted-directory`, `input-too-large`,
365
+ * and — on a model fan-out — `model-not-found` / `rate-limit`; see
354
366
  * [`crate::domain::fallback::startup_failure_reason`]).
355
367
  */
356
368
  fell_through: FallThrough[];
@@ -365,15 +377,29 @@ export interface FallbackReport {
365
377
  * One candidate a fallback run fell through, with the reason it could not run.
366
378
  */
367
379
  export interface FallThrough {
380
+ /**
381
+ * This candidate's own account of why it could not run: its
382
+ * [`RunResult::error`], copied — one value with one source, not a second
383
+ * rendering of it. `null` when the candidate said nothing beyond its status.
384
+ *
385
+ * So when the provider named the cause in machine-readable terms, what
386
+ * arrives here is the sentence naming the harness with that object **quoted
387
+ * inside it** (`… refused the request before running it:
388
+ * {"input_error_code":"input_too_large",…}`) — the object verbatim, not the
389
+ * object alone. A reader extracts it; nothing paraphrases it on the way.
390
+ *
391
+ * The `reason` above is oneharness's classification and stays a short,
392
+ * closed token; this is the cause underneath it, carried up so a supervisor
393
+ * reading only the fallback block never has to re-parse a fallen-through
394
+ * candidate's raw stdout to learn what the provider already said. Added in
395
+ * report schema `0.8`.
396
+ */
397
+ detail: string | null;
368
398
  /**
369
399
  * Canonical harness id.
370
400
  */
371
401
  harness: string;
372
- /**
373
- * Short reason token (`not-installed` / `spawn-error` / `auth` / `quota` /
374
- * `model-not-found` / `rate-limit`).
375
- */
376
- reason: string;
402
+ reason: FallThroughReason;
377
403
  [k: string]: unknown;
378
404
  }
379
405
  /**