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
//! The **effect vocabulary** (VISION §4.11 item 1) and the classification of one
//! invocation into it.
//!
//! The vocabulary classifies **invocations, never tool names**. That is the
//! whole reason the shipped grant stays whole-pool (bl-7fc8): `bash` is every
//! class at once, so a per-name allow-list is theatre and only per-invocation
//! adjudication can tell a `ls` from a `curl | sh`.
//!
//! Seven classes. Six are reaches, ordered by how far each goes past the job;
//! the seventh is the absence of one:
//!
//! | Class | Reaches |
//! |---|---|
//! | [`Read`](Effect::Read) | observes only |
//! | [`TargetWrite`](Effect::TargetWrite) | the writable root, or the world's own substrates through their gated verbs |
//! | [`Process`](Effect::Process) | mints agents or processes beyond the invocation |
//! | [`OpenWorld`](Effect::OpenWorld) | past the root and the world: network egress, host writes, a `cd` out |
//! | [`Destructive`](Effect::Destructive) | irreversible loss: history rewrite, forced refs, deletion past git's reach |
//! | [`Secret`](Effect::Secret) | credentials and environment |
//! | [`Opaque`](Effect::Opaque) | **unknown** — this control could not read what the invocation does |
//!
//! **There is no arm from a tool NAME to a passing class** (bl-72bd). Names are
//! folded into a closed enum first ([`intrinsic::Known`]) and matched
//! exhaustively, so a name added without a row does not compile; everything the
//! enum does not name goes to [`routed`], which reads the invocation's own
//! operands — a command line, then a `url` — and answers
//! [`Opaque`](Effect::Opaque) where there are none. The arm this replaced read
//! `other => OpenWorld`, and open-world passes: a foot's `box2_shell` running
//! `rm -rf` was therefore passed unread while the engine's own `bash` refused
//! the same line. Falling off a match into the most permissive class is the one
//! answer nobody chose, and it is now unrepresentable rather than merely fixed.
use Root;
use Request;
/// The input field a command line rides in — litany's own `bash` schema and
/// every thrall shell tool's ([`routed`]), said once here so the built-in and
/// the routed lane read the same field name and cannot drift.
const COMMAND: &str = "command";
/// The input fields a **network address** rides in — the `url` of every
/// fetch-shaped MCP schema and the `urls` of its batched form (bl-c6f0), said
/// here beside [`COMMAND`] because they are read the same way and for the same
/// reason: an operand of the invocation, never a claim it makes about itself.
const ADDRESS: = ;
/// The intrinsic map: the closed set of names this control implements a row
/// for, and the row each carries.
/// The two intrinsic rows judged against the writable root at consult time.
/// The fail-closed lane for every name the intrinsic map does not hold
/// (bl-72bd) — a foot's routed tool, or anything a later litany adds.
/// A tool's reach, in the seven-class vocabulary. Ordered: a higher variant is
/// a wider reach, which is what lets a compound command take the worst of its
/// parts without a table of pairs. [`Opaque`](Effect::Opaque) is highest
/// because an unread invocation may be any of them — the fold has to carry the
/// unknown outward, never let a known part bury it.
/// A classified invocation: its reach, and the one clause that says why. The
/// clause is what a refusal hands the model and a hold hands the operator, so
/// it names concrete things (the command, the path) and never a doc coordinate.
/// **The compactor's checkpoint pair** — the two names litany injects from the
/// calling role's own procedure and that its shipped `providers.yaml` says is
/// "never declarable here". They are machinery, not the agent's acts: the pair
/// writes the conversation's own summary onto its compactor branch and
/// nominates that same conversation's files, and nothing else.
///
/// It exists for the **floor** ([`judge::Answers::ruling`](super::judge::Answers::ruling))
/// and for nothing else. A floor is a statement about what the AGENT may do to
/// the world; the compaction procedure is confined by construction rather than
/// by adjudication — the same argument the grant already makes for it (bl-52b7)
/// — so a floor that held it would queue the operator a decision with no
/// decision in it and stall compaction under exactly the policy an operator
/// sets when they are most worried (bl-a821).
///
/// It reads the closed [`intrinsic::Known`] enum rather than the strings, so
/// the pair has one home: a rename upstream moves [`intrinsic::Known::of`] and
/// this follows it.
/// **Which leg an invocation runs on** (bl-1772). The engine's own tools run on
/// the machine the operator is sitting at; every other name is a tool a
/// registered machine advertises, executed on that machine (REMOTE §5). The
/// classifier already folds the two apart, and the *judgment* needs the same
/// fact, because a refusal delivered to the model is only an answer where the
/// model is not the party that can walk around it (see
/// [`Ruling::for_the_operator`](super::judge::Ruling::for_the_operator)).
/// Classify one invocation. Total over every tool name and every input shape:
/// an input that does not match its schema simply yields no operands, and a
/// name no row names goes to the [`routed`] lane rather than to a default arm.