1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
//! Ops-pane and surface-failure view-models (DESIGN §4.2, §7.3, §11).
//!
//! [`OpRow`] carries the **full** `ops.jsonl` entry (argv, cwd, exit, stdout,
//! stderr) so the ops pane can expand a row to the whole record — "a trail that
//! hides *why* is not a trail" (§7.3). What that `exit` field *means* — is the
//! row a failure, a drift, and how does its exit read in words — is the one
//! classification in [`super::exit`], which carries `OpRow`'s other half;
//! [`SurfaceFailure`]
//! is what the originating surface (start pane, input bar) holds as its §5.3
//! RAM item and paints in ichor red — argv + a stderr tail. Both are pure
//! projections of the durable ops line, so the surface's RAM item and the ops
//! pane never diverge (§5.3: "renders the durable fact from the pane").
use ;
/// How many trailing stderr lines the compact surface-failure view keeps: the
/// error's tail is where the cause lands; the ops pane expands to the full text.
const SURFACE_STDERR_LINES: usize = 3;
/// The one elision policy for [`OpRow::summary`] (bl-0bf9): a collapsed row is
/// a scan surface, one row per op — a prompt op's `argv` carries an arbitrary-
/// length, multi-line goal (a whole ball body is the ordinary case) that used
/// to flow into the list unwrapped, breaking the scan.
/// Past this many `char`s the summary is cut; this is the ONLY place `argv`
/// elides — the expansion (`cwd`/`exit`/`stdout`/`stderr`, §4.2) always carries
/// `argv` byte-exact.
///
/// **Where** it cuts is [`crate::elide::middle`]'s rule, not this file's
/// (bl-3aa1). The cut used to keep the head, which for an `argv` is the end
/// that does not distinguish it: every row opened
/// `litany <verb> … /home/<user>/.cache/…/data/yog/` — over half the row,
/// identical on every line — and the workspace leaf and agent id that told two
/// operations apart were exactly what fell off the end. A column of different
/// ops scanned as one repeated string.
const SUMMARY_ARGV_MAX: usize = 100;
/// One ops-pane row — the whole `ops.jsonl` entry, argv pre-joined for display.
/// Collapsed the pane shows `ts`/[`OpRow::summary`]/`exit`; expanded it shows
/// `cwd`, the byte-exact `argv`, `stdout`, and `stderr` (§11). No egui here —
/// the shell paints these.
/// The failure a surface paints in ichor red (§7.3): the attempted `argv` and
/// the tail of its `stderr`. Built from the same ops line the pane renders, so
/// the two never diverge.
///
/// It carries no origin of its own (bl-48f8). The attribution lives on the
/// durable row ([`OpRow::origin`]) and is the *question*
/// [`AppModel::last_failure`](crate::AppModel::last_failure) is asked — a
/// surface that named an origin to get this value cannot learn anything by
/// reading it back, and a second copy of one fact is how the two drift.
/// The last [`SURFACE_STDERR_LINES`] non-empty-trailing lines of `stderr`, the
/// cause the surface shows compactly. Empty stderr yields an empty tail.
///
/// `pub(crate)` since bl-55d8: this is the crate's **one** answer to "how much
/// of a stderr does a *surface* say", and the §7.3 no-response wound's banner
/// is a surface like the rest. A banner that quoted a different number of lines
/// than the ops row beside it would be two policies for one question.
pub