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
//! **The acts whose subject is the conversation, answered here** (REMOTE §5.4,
//! bl-dfce): the compactor's procedure pair `write_summary` /
//! `mark_for_deletion`, the four worker grants, and the two acts that read and
//! write the agent's own record — the set below is the enumeration.
//!
//! The seam inversion made the router *total* — while an injection is installed
//! it answers every invocation the agent makes, and nothing resolves a binary
//! behind it. litany has a second source of injected tool definitions besides
//! the host: the calling role's own procedure, which today is exactly these two
//! names. Under the inversion they reach yog's router like any other name.
//!
//! **They are not tools on a machine, so they are not a thrall's.** The
//! subject-locality invariant (REMOTE §5: *"a tool executes where its subject
//! lives"*) decides it and nothing else has to. `write_summary` writes the
//! conversation's own summary onto the compactor branch; `mark_for_deletion`
//! nominates that same conversation's files. Their subject is the conversation,
//! the conversation lives on the server, and the server is what yog holds — so
//! no machine is involved, no thrall is involved, and REMOTE §12's *front door
//! only* governs execution **on a machine**, which this is not. Shipping them
//! to a thrall would send a box that does not hold the world a request about
//! it. The operator's ruling states the principle it falls out of: context
//! management happens in yog.
//!
//! **litany defines what the pair does; yog only decides where.** The acts
//! themselves are the engine's (its `ARCH §2.7` compactor toolset: the summary
//! numbering, the refusal to nominate the dispatch entry, the staged `git rm`),
//! and none of it is restated here. yog performs them by re-entering the
//! engine's own front door — `<driver_target> tool <name>`, the third hop
//! litany's own resolution addressed before the inversion, with the caller
//! identity on the child's environment and the `tool_use` input on its stdin.
//! The child is yog, re-executed under the `litany` namespace by the world's
//! shim, standing in the same world; nothing of the compactor's semantics is
//! reimplemented, so the pair has exactly one definition and it is upstream's.
//!
//! **The invocation's own id rides the child's environment** (litany's §3.3
//! stdio contract as amended by upstream bl-e8d7): `LITANY_TOOL_ID` is the
//! `tool_use.id` the engine is recording this call under, so the id the child
//! reads and the `steps/<agent-id>/<NNN>/tools/<tool-id>/` directory it writes
//! beside cannot disagree. A routing host is handed that id on the call and
//! owes it on any spawn it makes, exactly as it already owes the caller
//! identity and the cwd — and `python` is the first act that cannot work
//! without it, because naming its own record directory is how it puts each
//! inner invocation's record where the engine expects one. **The routed leg
//! owes nothing here**: the spawn a machine makes is the foot's own, and the
//! id addresses a directory on the server's disk that no foot holds.
//!
//! **The tool control still sees them, and yog has no say in that.** litany
//! adjudicates in the tool window, *before* the executor is entered, for every
//! name including an injected one — so `yog tool-control` judges these two
//! exactly as it judges every other invocation, and the router (which lives
//! inside execution) could not exempt them if it wanted to. There is no
//! carve-out at the chokepoint, and none was needed.
use Path;
use Ordering;
use ;
use ;
use crate;
/// **The engine-act name set, closed and enumerated here and nowhere else.**
/// Ten rows since bl-9ced, in three families, each admitted by the
/// subject-locality invariant (REMOTE §5: *"a tool executes where its subject
/// lives"*) and by nothing else:
///
/// - the compactor's procedure pair (`write_summary`, `mark_for_deletion`,
/// REMOTE §5.4, bl-dfce) — the conversation's own summary and files;
/// - the conversation-subject worker grants (REMOTE §5.4 as amended by
/// bl-77be): `dispatch` mints and launches a child conversation on the
/// workspace the server holds, `message` deposits into another
/// conversation's inbox, `load_skill` copies a server-disk skill into the
/// agent's server-disk worktree, and `cd` writes the agent's
/// working-directory mark, a ref on the workspace. None of them is work on
/// a *machine*, so none of them is a thrall's — routing them anywhere would
/// send a box that does not hold the world a request about it.
/// - the four acts whose subject is the agent's own record, history and
/// lineage (bl-fe43, bl-81cc, bl-ebef, bl-9ced). `python` runs a program the model authored, and the
/// program composes the agent's own tools: the built-in generates a
/// `litany_tools` stub per tool this injection declares, each one a
/// `<driver_target> invoke` of the front door, and it writes each inner
/// call's record under the agent's in-flight `steps/<agent>/<NNN>/tools/`
/// (litany `docs/DESIGN_CODE_EXECUTION.md` §2.8). Both the step record and
/// the front door are the server's. `search_history` runs a fixed-string
/// pickaxe over the workspace's `agents/*` refs — every agent's transcript
/// (litany `docs/DESIGN_CONTEXT_ECONOMY.md` §4) — and a foot holds no
/// repository at all, so a routed one would search nothing and answer
/// *nothing found*, the worst answer a search can give. `remember`
/// (litany 0.0.11, upstream bl-3c11) appends one durable fact to `facts.md`
/// in a config commit on `proposal/<agent-id>` — a BRANCH of the workspace
/// repository the server holds, staged for the operator's `litany proposal
/// … --accept` — so it writes no file in the working tree at all, and a foot
/// that holds no repository could not perform it. It is also the door the
/// lineage refusal opened (upstream bl-d273, yog bl-baed): the act an agent
/// asked to remember something must reach instead of driving `litany config`,
/// which is now refused under `LITANY_TOOL_ID`. Routing it would put a
/// workspace-repository write on a box that does not hold the workspace.
/// `read_tool_output` (litany 0.0.12, upstream bl-9a6e) pages the cut middle
/// of one of *this agent's own* captures back out of
/// `steps/<agent-id>/<NNN>/tools/<tool-id>/output.json` — the diagnostic
/// record litany lands beside the step, on the server's disk, under a
/// domain bound that is one string equality against the caller's own
/// `LITANY_CONV_BRANCH`. Its subject is therefore the agent's record and
/// never a working tree, and a foot that holds no `steps/` tree could only
/// answer *no such address* — the same worst-answer `search_history` would
/// give. It is the recovery the bounded projection's cut marker names, so a
/// routed one would make the marker's own way out unreachable.
///
/// What is deliberately NOT here: `bash`, `read_file`, `apply_patch` — acts
/// at the conversation's working directory, which take the worktree lane
/// ([`super::subject`]) and reach a consenting machine when the operator
/// enrolled one. The lane's last rung calls [`perform`] below on them
/// ([`super::subject::performs`], bl-5710), so the mechanism is shared and
/// the *ordering* is what separates the two sets: an engine act never
/// consults the roster, a worktree name always does. An eleventh row is a
/// deliberate act with this audit's question asked again — never a prefix
/// test or a name shape, which is how a closed set stops being closed. The
/// strings are yog's own spelling: the engine keeps its constants
/// crate-private, so the names cross as text exactly as they do in the
/// model's `tool_use` block.
pub const NAMES: = ;
/// The `litany` verb the built-in front door answers under.
const VERB: &str = "tool";
/// The workspace root a tool's caller identity is read from, litany's spelling.
const CONV_REPO: &str = "LITANY_CONV_REPO";
/// The agent id half of the same identity, litany's spelling.
const CONV_BRANCH: &str = "LITANY_CONV_BRANCH";
/// The invocation's own id — the third variable of litany's stdio contract,
/// its spelling, and the name of the record directory the child writes beside.
const TOOL_ID: &str = "LITANY_TOOL_ID";
/// How often a running child is looked at — a latency knob on the answer, not
/// on the act.
const POLL: Duration = from_millis;
/// Whether `name` is one of the engine acts this module performs.
/// Perform one engine act and answer what it captured, or the sentence saying
/// why nothing did. A failure is the in-band non-zero refusal every other
/// answer on this seam is — the model reads it and steps on.
/// The re-entry itself: the identity on the environment, the input on stdin,
/// and the child's own three facts back untouched.
///
/// **Both waits are bounded** (litany's stated router obligations: carry your
/// own deadline, watch the stop flag). Returning early drops the stream, and
/// the drop is the kill — the same SIGTERM-then-SIGKILL cascade every other
/// child of this crate ends by.