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
//! **One opening or closing of the tool window** (REMOTE §5.5, bl-5305): the
//! datum the follow lane carries beside the model's prose, read off the
//! per-call record litany lands, and its JSON spelling.
//!
//! It sits beside [`Stream`](super::Stream) and for that type's reason exactly:
//! the shape of a fact read off the workspace's disk is this module's
//! vocabulary, and the boundary names it rather than restating it. What the
//! *follow lane* adds — which calls a given read has already spoken about — is
//! that lane's own ([`boundary::follow::tools`](crate::boundary::follow)),
//! exactly as [`Open`](crate::boundary::follow) is the lane's half of the fold.
//!
//! **Two events per call come off disk, and both are transitions.** litany
//! lands `input.json` immediately before it dispatches a call and `output.json`
//! when the capture returns (litany ARCH §3.3), so the pair of file existences
//! *is* the window opening and closing. A call's standing is what the two files
//! say the moment it is asked; nothing is stored.
//!
//! **The third transition never reaches disk, because it is what stops the call
//! from being dispatched** (bl-58bb). When the capability control answers
//! `hold`, litany's seam parks the invocation *before* the executor is entered
//! — so no `input.json` is landed and the window's two files say nothing at
//! all. The park's one record is the hold mark
//! ([`control::hold`](crate::control::hold)), which carries the same three
//! facts an opening event does: the `tool_use` id, the tool the model named,
//! and the control's reason. [`parked`] is that mark read as an event, so the
//! lane has one vocabulary for *what this call is doing* rather than a second
//! carrier beside it.
//!
//! **The client the call ran on rides in the name and is not joined here.** A
//! loaded remote tool is presented as `<client>_<tool>`
//! ([`loaded::Entry::presented`](crate::tool_host::loaded::Entry::presented)),
//! always and never only when ambiguous (REMOTE §5.1), so the name litany
//! recorded already says which machine the call was routed to. Splitting that
//! composition back apart would be a second reader of a rule with one home, and
//! asking the registry instead would answer *where it would route now* rather
//! than where it ran.
use BTreeMap;
use ;
use ;
use crate;
/// Filenames of the per-call record (litany ARCH §3.3). [`super::tools`] names
/// them too and reads them for a different question — what the latest step is
/// running, on the worker's cadence, for every agent at once — so the two
/// readers share the directory convention and nothing else.
const INPUT_FILE: &str = "input.json";
const OUTPUT_FILE: &str = "output.json";
/// The step directory's tool subtree.
pub const TOOLS_SUBDIR: &str = "tools";
/// How much of a call's input one event carries. A tool input is arbitrary JSON
/// — a whole file body is an ordinary write argument — and this lane exists to
/// be read *while* it streams, so the summary is bounded exactly as the §4.2
/// trail's argv summary is, through [`crate::elide::middle`]: the cut keeps
/// both ends, because the head of a command line says which command and the
/// tail says which invocation of it.
const INPUT_MAX: usize = 240;
/// One opening or closing of the tool window (REMOTE §5.5).
///
/// **The capture's status is the exit code's presence, not a second field.**
/// Absent is a call in flight and present is one whose capture landed, so the
/// two readings cannot disagree and there is no arm for "complete, status
/// unknown".
/// The call directories under one step's `tools/`, keyed by `tool_use` id and
/// ordered by it — the provider mints those ids in call order and `read_dir` is
/// unordered, which is the ordering rule [`super::tools`] already applies. A
/// directory with no `input.json` is a call still being landed, not a call; an
/// absent or unreadable `tools/` is an empty listing, which is the general path
/// with no input rather than an error with an opinion.
pub
/// Whether this call's capture has landed — the closing half of the window.
pub
/// **The window parked** (bl-58bb): the call the capability control held, off
/// the mark litany's seam wrote instead of dispatching it.
///
/// It carries the mark's three fields and adds nothing. The reason is the
/// control's own sentence — the tool, an input summary, the computed class and
/// the evidence — so this event says what an opening says *and* why nothing
/// ran, in the text the attention item and the agent row already show.
pub
/// The window **opening**: what is about to run, and — through the name — where.
pub
/// The window **closing**: the same identity, and the status the capture landed
/// with. It restates neither the name nor the input — a follower holds the
/// opening event those rode on, keyed by the same id, and a second copy of one
/// fact is exactly what this lane's byte budget was cut for (bl-3655).
///
/// A record whose `exit_code` is unreadable answers `0`: the file's presence is
/// what "the capture landed" means, and a closing event carrying no status at
/// all would be indistinguishable from the opening one.
pub
/// One record, or `None` for a file that is absent, unreadable or caught
/// mid-write — the same tolerance every other reader of a litany record has.
/// One event's JSON spelling. `tool` and `input` are absent on a closing event
/// and on a record that carried neither; `exit_code` is absent for a call in
/// flight, and `held` for one no control parked — each the fact itself and not
/// an omission.
/// Read one back. Strict on `tool_use`, which is the identity a follower keys
/// on, and on a present field of the wrong shape; forgiving of an absent one,
/// which is a reading (module doc).