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
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
//! **What a gesture earns**, as a type (§8.5) — the boundary's one answer
//! enum, cut off `reply.rs` at §12's pre-split band on the seam `start/model`
//! already uses: the inert shape a caller reads, beside the modules that say
//! it. Nothing here derives, encodes or decodes anything; each variant is one
//! outcome and its doc is why that outcome is its own row.
use crate::actions::verbs::Outcome;
use crate::board::Board;
use crate::nav::convs::ConvRow;
use crate::opslog::OpView;
use crate::projects::join::JoinRow;
use crate::search::Found;
use crate::start::Prepared;
use super::ws_row::Workspaces;
/// The typed answer a gesture earns. Exhaustive over the boundary's outcomes;
/// an error path is the `Err(String)` beside it, encoded by [`refusal`].
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Reply {
/// A short verb's captured run (§8.2) — `ok` iff exit 0.
Outcome(Outcome),
/// The `prepare` action's product: the composer's fire-time parameters.
Prepared(Prepared),
/// The `fan` action's product (§3.8): one `prepare` reply per candidate,
/// rebound to its own attempt worktree and ready for the ordinary `prompt`.
Fanned(Vec<Prepared>),
/// The `retire` action's product: `discarded` says whether the retention
/// policy also took the source ref — what the policy *did*, never what was
/// asked, since an undeclared retention keeps it.
Retired {
discarded: bool,
},
/// The `deliver` action's product (VISION V3.2): the identities one
/// candidate's delivery acted on — a receipt, never a stored winner; the
/// standing fact is the tagged squash the target's history now carries.
Delivered(crate::fan::Delivery),
/// The `prompt` action's product: the minted conversation name (§3.3).
Started {
conversation: String,
},
/// The §3.6 unmaking completed.
Deleted,
/// The VISION §4.9 monitor's arming landed: `armed` says which way.
Armed {
armed: bool,
},
/// An attention item was raised on a conversation (VISION §4.9).
Flagged,
/// A parked invocation was answered (§8.6): which `tool_use` the answer
/// landed on, the tool it names, the answer written — verdict **and the
/// scope it now stands over** (bl-94a5) — and whether the releasing
/// `litany advance` was launched. It answers with the *held invocation*
/// rather than the queue that remains (the `seen` precedent): the mark
/// lifts only once the re-adjudication runs, so a queue read here would
/// still show the park it just answered — a receipt that lied.
Answered(crate::boundary::control::Answered),
/// **A queue item acknowledged** (§6, bl-5cfe) — `seen`'s receipt: what the
/// watermark landed on, and the queue that remains beside it. The remainder
/// alone was the whole answer, and it reads as a plain `attention` — the
/// acted-on row is precisely the row it no longer holds, so the one act it
/// reports is the one thing it could not say (the
/// [`Answered`](Self::Answered) precedent, one verb over: a receipt must
/// not lie). The queue stays: the loop is one gesture per decision.
Acknowledged(crate::boundary::answer::queue::Acknowledged),
/// A conversation's capability floor was written (§8.6, VISION §4.9's
/// fifth rung): whether one **stands** over it now — re-derived from the
/// trail after the write, never an echo of the direction that was asked
/// (the [`Marks`](Self::Marks) precedent). The two differ exactly where it
/// matters: restoring a conversation whose ancestor is still floored leaves
/// it floored, and a receipt saying otherwise would be a lie.
Floored {
standing: bool,
},
/// The nudge's driver was launched (§8.2, bl-9bef): `litany advance` is
/// running detached against the conversation. It answers with nothing else
/// because there *is* nothing else yet — what the model does with the turn
/// arrives on the transcript and the §4.2 trail, at its own pace, and a
/// receipt that guessed at it here would be a receipt that lied.
Nudged,
/// The §4.2 ack line landed — every current alarm is acknowledged.
Acked,
/// The trail was truncated; the clear is the fresh trail's first row.
TrailCleared,
/// The §9 config file the gesture named landed (bl-3f46). A lineage write
/// answers with its `litany config` run ([`Outcome`](Self::Outcome))
/// instead — a write and a spawn earn different receipts, here as
/// everywhere else on the boundary.
///
/// **It carries nothing** (REMOTE §8, bl-ccf7). It used to carry the
/// absolute path that now held the text, which was the last of §8's
/// path-typed residuals to have a computable answer: a
/// [`ConfigFile`](super::config::ConfigFile) determines its own location
/// exactly — the wall's `config.toml`, `models.yaml`,
/// `workflows/<name>.yaml`, `cadence.yaml` — so the field was a second
/// representation of the destination the gesture had just named, spelled
/// as an operator's home root a client on another machine could neither
/// use nor unsee. The receipt says *that* it landed, which is the whole of
/// what a write can add to the address it was given — the
/// [`Nudged`](Self::Nudged) / [`Acked`](Self::Acked) /
/// [`TrailCleared`](Self::TrailCleared) shape.
Applied,
/// The agent's tracking branch (§16.3), **re-read after the write**: what
/// actually landed, never an echo of what was asked.
///
/// **The space it landed in is not answered** (REMOTE §8, bl-ccf7). It was,
/// on the argument that "which branch" and "whose branch" are one question
/// — but since the §16.3 per-agent ruling a workspace's marks space is
/// always its own (`<wall>/marks`), so
/// [`marks::read`](crate::world::marks::read) is a pure function of the
/// workspace the gesture already named and the field could answer nothing
/// else. One computable fact, spelled twice, and the second spelling was an
/// absolute path.
Marks {
branch: String,
},
/// A tool host's set landed (REMOTE §5, bl-4e08), and **whether this
/// engine WROTE it** (REMOTE §5.1, bl-66d4, PROTOCOL 8). It carried nothing
/// until then, on §8.1's own test — the stored set after the write *is* the
/// set the gesture carried, so an echo would be one computable fact said
/// twice, the [`Applied`](Self::Applied) shape — and that test still rules
/// out an echo. What it does not rule out is this: `wrote` is not the set,
/// it is what happened to the DOCUMENT, and no other party can compute it.
///
/// It is false on the ordinary re-presentation, which every reconnect and
/// every §5.3 hand-off makes. A `true` on any later re-assertion is the
/// advertising box learning that something blanked or replaced its set
/// while it was absent — the one event bl-4e08's traffic ruling made
/// undetectable from that end, reported here rather than in a trail that
/// only this side reads.
Advertised {
wrote: bool,
},
/// **One device enrolled** (REMOTE §8.4, bl-f4e3): the QR envelope's whole
/// payload, and the only moment the minted key exists off the device it is
/// for — [`enroll::Enrolled`](crate::registry::enroll::Enrolled)'s fields.
Enrolled(crate::registry::enroll::Enrolled),
/// **One routed invocation, and its capture if it has one yet** (REMOTE §5,
/// bl-024b) — the answer to all three gestures of the routing leg's asking
/// side, because they are one subject at three moments: `invoke` has just
/// queued it (`capture` absent), `complete` has just answered it, and
/// `capture` is the poll in between. One variant rather than three, on
/// [`Marks`](Self::Marks)' own terms: what is answered is the slot **as it
/// stands after the call**, never an echo of what was asked.
Routed {
invocation: String,
capture: Option<crate::registry::mailbox::Capture>,
},
/// What this tool host has been asked to run (REMOTE §3) — the
/// follow-class read's answer. Empty is the ordinary answer of a hold that
/// expired with no work, not a failure: the host asks again.
Invocations(Vec<crate::registry::mailbox::Invocation>),
/// The altitude-0 chrome (REMOTE §9.7, bl-b4b5): the enumerated workspaces
/// with their §6 rollups and §4.1 pin ranks, and the §7.2 currency of the
/// derivation they came off.
Workspaces(Workspaces),
Conversations(Vec<ConvRow>),
Balls(Vec<JoinRow>),
/// **One workspace's bound balls with their §3.5 figures** (§3.2, §11
/// balls section) — [`WorkspaceBalls`](super::Query::WorkspaceBalls)'
/// answer. The §11 strip, the roster rows, the ▶ Continue menu's object and
/// the settings band's per-ball figures are all selections out of this one
/// listing (`nav::balls`), which is what makes them one ask.
WorkspaceBalls(Vec<crate::nav::BoundBall>),
/// The V4 board (VISION §5 V4) — the columns, their rows, and each row's
/// gates, drones and figures.
Board(Board),
/// The §6 decision queue (VISION §5 V5.2): what is waiting on the operator
/// — [`Attention`](super::Query::Attention)'s answer.
Attention(Vec<crate::boundary::answer::queue::QueueRow>),
Ops(Vec<OpView>),
/// What a command does (§8.5): the whole roster, or one verb's page.
Help(Vec<crate::boundary::help::HelpRow>),
/// What matched (§8.5): the ranked hits *and* the sources that could not be
/// read, because an answer that hid the second half would be a lie about
/// the first.
Search(Found),
/// What the workspace's attempts changed in their project (§5.1 #32), and
/// the named file's patch when the query asked for one.
WorkDiff {
attempts: Vec<crate::workdiff::Attempt>,
patch: Option<crate::files_view::Preview>,
},
/// **The attempt science projection** (§3.9, VISION §4.10 item 7) —
/// [`Science`](super::Query::Science)'s answer: one row per delivery
/// attempt, each carrying the [`WorkDiff`](Self::WorkDiff) row it composes
/// plus the agent-side join — frozen inputs, usage, wall time, verdicts and
/// the derived outcome. Nothing in it is stored anywhere.
Science(Vec<crate::science::Attempt>),
/// **The conversation** (§11, bl-6233) — [`Transcript`](super::Query::Transcript)'s
/// answer: the committed `messages/` entries with the in-flight tail folded
/// on, which is the whole of what the window's chat pane paints.
Transcript(crate::transcript::Transcript),
/// **One frame of the live tail** (REMOTE §3, §5.5; bl-73e7, bl-3655,
/// bl-5305) — [`Follow`](super::Query::Follow)'s answer: the prose fold and
/// the tool window, both **appends**. One variant over
/// [`FollowFrame`](super::FollowFrame) rather than two fields here, the
/// fold six families already take; that type's own doc carries the rule and
/// why the second half exists.
Follow(super::FollowFrame),
/// **A sign-in's standing** (REMOTE §8.3, bl-c285) — the receipt
/// [`Login`](super::Action::Login) earns *and* one
/// [`LoginTail`](super::Query::LoginTail) frame, which are the same value
/// at two moments: a frame carries what the standing gained since the frame
/// before it, and the one carrying an outcome is the last.
Login(crate::login::LoginView),
/// Every step the conversation has taken (§11) —
/// [`Steps`](super::Query::Steps)' answer, the Steps tab's list.
Steps(crate::steps_view::StepsView),
/// One step's records drilled in (§11) — [`Step`](super::Query::Step)'s
/// answer, the parsed records and the capture logs that had bytes. A step
/// the tree does not hold answers absent records rather than refusing:
/// "nothing was written there" is a reading, not an error.
Step(crate::steps_view::StepDetail),
/// The agent worktree's listing and, when the query named a listed file,
/// its bounded preview (§11) — [`Files`](super::Query::Files)' answer. The
/// [`WorkDiff`](Self::WorkDiff) shape, because it is the same question:
/// what is here, and what does this one say.
Files {
view: crate::files_view::FilesView,
preview: Option<crate::files_view::Preview>,
/// **Where this conversation actually works, when that is not the
/// directory `view` listed** (bl-1015) — litany's own
/// `refs/litany/cwd/<agent-id>` mark, which §3.3 calls *"the one
/// channel"* for the work target: a path or ball rung seeds it at
/// creation, so every tool step of every turn runs there and the
/// agent worktree this listing walks holds none of the work.
///
/// `None` is the case where the promise holds — a bare start, whose
/// tools run in the listed worktree — so a reader never has to tell
/// "bound elsewhere" from "bound here", exactly as
/// [`FilesView::AbsentWorktree`](crate::files_view::FilesView) spares
/// it telling a torn-down worktree from an empty one.
///
/// It is a **statement, not a listing**: yog does not walk it. The
/// listing is still the agent worktree, and this says outright that
/// the work products are somewhere this read does not reach and where
/// that is — which is QUALITY H2 (*"a fact yog cannot derive is
/// answered as absent and never as a zero"*) applied to a listing.
/// Without it a conversation that built its whole deliverable in the
/// bound directory answered a normal listing of goal and soul, and
/// nothing anywhere said the work had gone elsewhere.
working_dir: Option<std::path::PathBuf>,
},
/// The config commit a conversation resolves its policy from (§9.3, §5.1
/// #17) — [`Governing`](super::Query::Governing)'s answer, the §11 Config
/// tab's whole content and VISION V1.2's *config-frozen-at* spelled, with
/// the lineage it follows or the divergence holding it. The one
/// member of the family that answers a **derivation over the workspace's
/// git** rather than a listing, so it refuses where the others answer
/// absent: a conversation always has a policy, and "none" would be a lie.
///
/// **The workflow mark rides beside the commit** (REMOTE §9.24, bl-b680):
/// the mark is a fact about the *agent's descent* and the config is a fact
/// about a *commit*, so the reply joins them rather than either lying
/// about the other — `None` is the general path, the followed tip's
/// `workflow.yaml` governing; `Some` names the commit that overrides it,
/// and who on the descent holds the mark ([`workflow`](super::workflow)).
Governing {
config: crate::config_edit::branch::GoverningConfig,
workflow_mark: Option<crate::config_edit::branch::workflow_mark::WorkflowMark>,
},
/// The step spine (VISION V1) — [`Rail`](super::Query::Rail)'s answer: the
/// notches and the child cards hanging off them, unpinned. The pin is the
/// viewport's, and §8.5 files a viewport's folds under views.
Rail(crate::rail::Rail),
/// One agent's undelivered deposits (§11, ARCH §2.11) —
/// [`Inbox`](super::Query::Inbox)' answer.
Inbox(Vec<crate::inboxview::InboxEntry>),
/// One conversation as a seat sees it (REMOTE §9.4, bl-1eb0) —
/// [`Agent`](super::Query::Agent)'s answer: the §11 centre pane's identity
/// line, mark row, live badge and §8.2 gates, none of which had a spelling
/// any face but the window could read.
Agent(crate::boundary::answer::agent::AgentView),
/// **What a §9 config read answers** (bl-dd88) — one variant over
/// [`ConfigAnswer`](super::ConfigAnswer), the carrier matching the
/// questions' own ([`config::Read`](super::config::Read)). The five reads
/// folded in bl-719a and their answers did not, so the roster named the
/// family once on the asking side and five times here; that type's own doc
/// carries each member and why the fold changes no wire spelling.
Config(super::ConfigAnswer),
/// The workspace's registered clients with their presence and advertised
/// sets (REMOTE §5, bl-4e08) — [`Clients`](super::Query::Clients)' answer,
/// and the payload the navigator's clients section paints.
Clients(Vec<crate::registry::roster::ClientRow>),
/// **Is this box wired up?** — [`Doctor`](super::Query::Doctor)'s answer,
/// one row per check; the reasoning is [`doctor`](crate::doctor)'s own.
Doctor(Vec<crate::doctor::Row>),
/// **The price table, the ceiling and the world's ledger** (DESIGN §3.5;
/// bl-53d1) — [`Prices`](super::Query::Prices)' answer and the receipt
/// both spend acts earn, re-derived after the write rather than echoed
/// (the [`Marks`](Self::Marks) precedent); [`PricesView`](super::PricesView)'s
/// own doc carries the three absences it can say.
Prices(super::PricesView),
}