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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
//! **The census of what an engine can answer** — the kinds this window draws,
//! and the captured run three of the ops on this surface come back as.
//!
//! Split from [`super`] at the 300-line cap on the seam that module's own doc
//! already draws: [`super`] is *the reading* — the three outcomes one frame
//! can be, the four-rung policy every decoder obeys, and the module list — and
//! this is *what an answer turned out to be*. The first changes when the
//! policy does, which is almost never; the second every time a pane lands, and
//! that asymmetry is the whole reason a seam is here.
//!
//! **[`Reply`] is the one census** and DESIGN §4.9 holds the ledger of what a
//! later pane adds: a kind nothing renders is a kind nobody has to carry, and
//! the ball that lands a pane is the ball that adds its kind.
use super::{
agent, balls, board, clients, config, convs, diff, enrolled, files, governing, help, inbox,
lineages, login, ops, proposals, providers, queue, rail, roles, roster, science, search, start,
step, steps, stream, transcript,
};
/// **The kinds the window draws.** Thirty-three, and each is here because a
/// surface paints it; DESIGN §4.9 holds the ledger of what a later pane adds.
#[derive(Debug, Clone, PartialEq)]
pub enum Reply {
/// A short verb's captured run — what a deposit, a stop or a ball verb
/// earns. `ok` is `exit == 0` and is read off the exit code alone.
Outcome(Outcome),
/// The detached advance was launched. It carries nothing because there is
/// nothing yet: what the model does with the turn arrives on the
/// transcript, at its own pace, and a receipt that guessed at it would be
/// a receipt that lied.
Nudged,
/// The enumerated workspaces with their rollups — the roster, and how
/// current the derivation behind it is.
Workspaces(roster::Workspaces),
/// One workspace's conversation list.
Conversations(Vec<convs::ConvRow>),
/// **What one workspace's roles are set to** — the read the tuning pane
/// opens on, and the read back of what its own three writes landed. It is
/// a listing rather than a map: the engine's order is the config's order,
/// and a seat that re-sorted it would be holding a second opinion about a
/// file it did not write.
Roles(Vec<roles::RoleRow>),
/// One conversation's committed entries with the live tail folded on —
/// the whole of what the chat pane paints.
Transcript(transcript::Transcript),
/// **Everything waiting on the operator**, across every workspace the
/// engine can see — the decision queue's rows, standing while its pane is
/// open (bl-f0ef). It is the answer to two ops rather than one: `attention`
/// asks for the whole queue and `seen` answers with the queue that remains,
/// so a reading of it is never a receipt to discard.
Attention(Vec<queue::QueueRow>),
/// **The parked invocation was answered** (§4.34, bl-bce2): which call the
/// answer landed on, the verdict written, and whether the release actually
/// drove the conversation on.
///
/// It answers with the **held invocation** rather than with the queue that
/// remains, which is upstream's own decision and the reason the seat can
/// say anything at all: the mark lifts only once the re-adjudication runs,
/// so a queue read here would still show the park it just answered.
Answered {
tool: String,
tool_use: String,
/// The verdict written, carried verbatim ([`super`]'s rung 3).
verdict: String,
/// **How far the answer stands** (PROTOCOL 18): the held call, the
/// conversation and its descent, or the workspace. Read back rather
/// than assumed from what was asked — the engine narrows a wide answer
/// on a destructive or credential-reaching call, so the receipt is the
/// only place the reach the boundary actually took is stated. Carried
/// verbatim on rung 3, like the verdict beside it.
scope: String,
/// Whether the releasing advance was launched. `hold` never launches
/// one, and that is the operator saying *stay parked*.
advanced: bool,
},
/// **The spread's product** (§4.36): one staged body per candidate, each
/// rebound to its own attempt worktree and ready for the ordinary
/// `prompt`. It is a listing of exactly the value
/// [`Prepared`](Self::Prepared) carries one of, because upstream encodes
/// it with the same encoder — so a candidate and a single staged start are
/// one type here, and firing n is firing one, n times.
Fanned(Vec<start::Prepared>),
/// **A candidate was accepted** (§4.36): the identities its delivery acted
/// on. It is a receipt and never a stored winner — the standing fact is
/// the tagged squash the target's history now carries — so it is four
/// scalars and no type of its own, exactly as
/// [`Answered`](Self::Answered) is.
///
/// **Two of the four are optional and each absence is a fact**, upstream's
/// own: no `source` is a source ref that was not there, and no `commit` is
/// a delivery that landed nothing. The target and the pinned base it
/// validated against are always said, because a delivery is about them
/// whether or not it moved anything.
Delivered {
base: String,
target: String,
source: Option<String>,
commit: Option<String>,
},
/// **A candidate's worktree was released** (§4.36): `discarded` says
/// whether this project's declared retention also took the source ref.
///
/// It reports what the policy DID and never what was asked, which is why
/// the seat paints it rather than predicting it: an undeclared retention
/// keeps the ref, and a seat that said so on its own would be a second
/// authority on a file it has not read.
Retired { discarded: bool },
/// **A capability floor was written** (§4.34, bl-bce2): whether one
/// **stands** over the conversation now.
///
/// Re-derived from the engine's trail after the write rather than echoed
/// back from the direction that was asked, and the two differ exactly
/// where it matters: restoring a conversation whose ancestor is still
/// floored leaves it floored, and a receipt saying otherwise would lie.
/// It is one field, so it is carried as one.
Floored { standing: bool },
/// **A flag was raised**, and the row it lands on arrives on the next
/// [`Attention`](Self::Attention). It carries nothing for the reason
/// [`Nudged`](Self::Nudged) carries nothing — what changed is on the queue,
/// and a receipt that restated it would be this end predicting a listing.
Flagged,
/// **The steps the selected conversation's loop has taken** — one half of
/// what the records pane paints, standing while it is open (bl-2cf7).
Steps(steps::Steps),
/// **What the selected conversation's worktree holds** — the other half,
/// on the same standing (bl-2cf7).
Files(files::Files),
/// **The selected conversation's spine** — every operable commit it has
/// and the children dispatched off them, on the records pane's standing
/// (§4.28, bl-b52c). It is the read the `fork` control's one argument is
/// discoverable off, which is why the two landed together.
Rail(rail::Rail),
/// **The conversation's own row, whole** — the header the records pane
/// opens with, on that pane's standing (§4.32, bl-3257). The largest shape
/// on this surface, and the one the seat reads most of a conversation from.
///
/// **Boxed**, and it is the only variant here that is: at twenty-one
/// fields over five nested objects it is several times the size of every
/// other, so carrying it inline would widen `Reply` — and therefore every
/// `Read` this window moves across the lock — to the size of the largest
/// answer the seat has ever learned to paint.
Agent(Box<agent::Agent>),
/// **One step's records** — the drill-in under the steps list, addressed
/// by the `seq` those rows paint (§4.32, bl-3257). POSTED rather than
/// standing: it is asked about one row, on a control, and re-asked freely.
///
/// **Boxed**, beside [`Agent`](Self::Agent) and for the same reason: four
/// records, a stream, a tool listing and two bounded logs is the second
/// of the two shapes on this surface big enough to widen every `Read`
/// this window moves across the lock.
Step(Box<step::Step>),
/// **The undelivered mail** waiting in that conversation's inbox — the
/// records pane's sixth read, on the same standing (§4.32, bl-3257).
Inbox(Vec<inbox::Row>),
/// **The config commit that conversation resolves its policy from** — the
/// spine's other half, on the same standing (§4.28, bl-b52c). Its `oid`
/// changed meaning at PROTOCOL 5 under an unchanged spelling, and
/// `governing`'s own module doc is where that is written down.
Governing(governing::Governing),
/// **One engine's own verb table** — what the commands pane paints, and
/// the same rows the parity roster is generated from (bl-40ec). It names
/// no workspace, so it is one channel's answer and the pane is the union.
Help(Vec<help::HelpRow>),
/// **What a needle found**, across everything one engine can see — the
/// find pane's answer, on the same fanned terms (bl-40ec).
Found(search::Found),
/// **The whole box's ball⇄workspace binding table** — the ball pane's
/// widest read (bl-d2af). It names no workspace, so it is one channel's
/// answer and the pane is the union.
Balls(Vec<balls::BallRow>),
/// **One engine's fleet board** — every live ball in its column, and the
/// armed loops running them, which is the only place a loop's own facts
/// are answered at all (bl-d2af). It names no workspace either.
Board(board::Board),
/// **The balls one wall holds**, with what each has cost — the ball pane's
/// aimed half, standing on the pane exactly as the roles read does.
WorkspaceBalls(Vec<balls::BoundBall>),
/// **The branch a wall tracks its tasks on**, re-read. It is one field, so
/// it is carried as one rather than wrapped in a struct with nothing else
/// in it.
Marks { branch: String },
/// **The trail one engine keeps** — every action that crossed its boundary,
/// standing while the trail pane is open (bl-4c48). It names no workspace,
/// so it is one channel's answer and the pane is the union.
Ops(Vec<ops::OpRow>),
/// **What this wall can sign in to** — the login pane's first read,
/// standing while it is open (bl-e3c5). It is the engine's listing order,
/// which is brazen's own routing order, and a seat that re-sorted it would
/// be holding a second opinion about a table it does not own.
Providers(Vec<providers::ProviderRow>),
/// **The machines registered in one workspace** — the clients pane's one
/// read, standing while it is open (bl-e53c). Presence is answered at the
/// moment it is asked and the advertised set is what that machine last
/// presented, which are two lifetimes on one row and are painted as two.
Clients(Vec<clients::ClientRow>),
/// **One config file's bytes, and the settings its schema found in them**
/// — the config pane's second read, standing on the destination it is
/// pointed at (bl-5c53; DESIGN §4.30).
Config(config::Config),
/// **The config lineages one workspace holds** — that pane's first, and
/// the listing its two pickers are filled from.
Lineages(Vec<lineages::Lineage>),
/// **What a reviewer has staged for this workspace's config**, and — when
/// the read named one — that proposal whole (REMOTE §9.22, PROTOCOL 18).
/// The learning loop's operator half: a candidate config commit is the
/// same subject `lineages` browses and `config` writes, one branch away
/// from governing anything.
Proposals(proposals::Proposals),
/// **The watermark landed** (bl-b8f7). It carries nothing for the reason
/// [`Flagged`](Self::Flagged) carries nothing: what changed is on the
/// trail, and the standing read answers `acked` on the rows that were
/// standing — this end predicts neither.
Acked,
/// **The trail was truncated**, on exactly those terms. What the new trail
/// holds is its own first row, and the standing read is what says so.
TrailCleared,
/// **Whether a standing thing is now standing** — the receipt `fleet`,
/// `disband`, `arm` and `disarm` all answer with (bl-a43a). It is ONE kind
/// for two families — the fleet loop and the alignment monitor — so a seat
/// cannot tell which it answers from the reply and must read the `op` back
/// (`crate::ui::model::absorb::Model::receipt`, DESIGN §4.33).
Armed(bool),
/// **Every delivery attempt of one workspace** — the fleet pane's first
/// read, standing while it is open (bl-a43a). It is derived when asked, so
/// the same row a minute later is a different statement.
Science(Vec<science::Attempt>),
/// **What one workspace's agents changed** — the fleet pane's second read,
/// on the same standing. It is the rows and nothing else: the `patch` a
/// named file would answer with rides through unread, because no gesture
/// this build composes can ask for one.
Work(Vec<diff::Diff>),
/// **What one provider row is offering** — the same pane, one depth down,
/// and posted rather than standing: a model list is fixed for the life of
/// a provider's own answer, so a standing read would spend a round trip a
/// beat forever on something that cannot change under the operator.
Models(Vec<String>),
/// **One sign-in run**, whether it is the act's own receipt or a frame of
/// the lane that follows it — upstream answers both with this kind,
/// because they are the same value at the same moment (REMOTE §8.3).
Login(login::Signin),
/// One frame of the live tail, and the whole accumulated stream rather
/// than a delta: a frame **replaces** what a seat holds, so nothing has to
/// be reassembled and a follow lane needs no second parser.
Follow(stream::Stream),
/// **A start, staged.** The fire-time parameters as the engine settled
/// them, which the next act hands straight back — the one reply on this
/// surface a seat has to hold between two gestures.
Prepared(start::Prepared),
/// **A new box's material** — the one reply on this surface that carries a
/// secret, held while a symbol is on screen and written down nowhere
/// (REMOTE §8.4; DESIGN §3).
Enrolled(enrolled::Enrolled),
/// **A start, fired**, and the name the engine minted for it. It carries
/// nothing else for the reason [`Nudged`](Self::Nudged) carries nothing:
/// what the model does with the turn arrives on the transcript. What is
/// new is the name, and the name is an address the reply just made
/// answerable.
Started { conversation: String },
}
/// A captured run: what the child said and how it ended.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Outcome {
/// The child's exit status.
pub exit: i32,
pub stdout: String,
pub stderr: String,
}
impl Outcome {
/// Whether the run succeeded. **Derived from the exit code**, never read
/// off the `ok` beside it: one fact with one home, and a second copy could
/// only ever disagree with it.
pub fn ok(&self) -> bool {
self.exit == 0
}
}