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
//! The world's **agent tools** — `<yog-data-root>/world/tools/` (DESIGN §16.4,
//! §16.7 W9). This module owns that directory end to end: the shim files yog
//! seeds into it and the `PATH` entry that makes them the tools an agent finds.
//!
//! **The surface an agent actually uses is bash.** §16.4's premise — "binaries
//! matter only as the plane on which litany's worker agents drive tools by
//! bash" — decides the mechanism: a worker types `bl close bl-1a2b` in its
//! `bash` tool, so `bl` must *resolve* to yog's embedded balls, not to whatever
//! host binary sits on the ambient `PATH`. Hence two facts, both here:
//!
//! 1. [`ensure_shim`] seeds `<world>/tools/bl` — a `/bin/sh` re-exec of yog's
//! own executable under the `bl` namespace (`yog bl "$@"`, the multi-call
//! pattern of `--editor-apply` / `yog env`, §8.4). It is written from the
//! [`Cli`] yog itself spawns ([`Cli::exec_words`]), so the shim and yog's own
//! `bl` spawns cannot name different targets — one fact, one home.
//! 2. [`prepend_path`] puts that directory in front of the ambient `$PATH` in
//! the world override set (§16.2), so every child of yog — the detached
//! `litany prompt`, its driver, the driver's `bash` tool, the shim — inherits
//! a `PATH` on which the world's `bl` wins.
//!
//! **Identity rides the env, not the argv.** The shim passes the caller's
//! arguments through verbatim; the `--as` stamp §3.3 promises is applied where
//! balls actually reads it — the embedded arm's `Edge::default_actor`, which
//! prefers `$YOG_NAME` over `$USER` ([`crate::multiplex`]). An explicit `--as`
//! still wins, exactly as it would have over an argv-appended flag, and verbs
//! that take no `--as` are untouched. That is why nothing here parses argv.
//!
//! **Convergent, never authoritative.** The shim is a generated artifact (§5.2):
//! `ensure_shim` rewrites it whenever its content differs — a reinstalled yog at
//! a new path converges on the next start — and deleting the whole directory
//! loses nothing. Convergence is not unconditional, though: a rewrite is only
//! ever an improvement if the new target is one that can be exec'd, so
//! [`ensure_shim`] refuses a resolution that is not an absolute path (bl-f558)
//! rather than replacing a working shim with a broken one. It is *not* the `litany-tool-<name>` external-tool slot: that
//! is litany's JSON-stdin tool contract under `$LITANY_HOME/tools/`, needs a
//! schema plus a `SKILL.md` plus a role `tools:` entry, and speaks nothing like
//! bl's argv (see §16.4's amended note).
use fs;
use io;
use ;
use crate;
use crateshell_quote;
/// The agent-tool namespace whose shim the start seeds (§16.7 W9): the `bl` an
/// agent's bash finds. Seeded at `Step::EnsureSeeded`, before any driver exists
/// to run one.
pub const BL: &str = "bl";
/// The `litany` shim namespace (§16.7 W11). Converged by the multiplex arm on
/// the way into every `yog litany` verb — it is `Fx::driver_target`, the single
/// path every litany re-entry (the detached `advance` launch, the §6 successor
/// `execve`, the tool resolver's third hop) spawns verbatim, so it must exist
/// before the first driver runs and must carry the namespace word a bare yog
/// exe cannot.
pub const LITANY: &str = "litany";
/// The `bz` shim namespace (§16.7 W11): `Fx::adapter_target`, the provider
/// adapter a linked litany spawns — the same single-path constraint as
/// [`LITANY`], answered by the W10 `bz` arm. Converged beside it.
pub const BZ: &str = "bz";
/// The `bl-delivery` shim namespace (bl-2930): balls' delivery plugin sibling.
/// Not an agent-facing tool — it exists so the embedded `bl prime` can bind
/// the checkout's plugin chain to absolute paths that ARE yog: the `bl` arm
/// hands balls `world/tools/bl` as its executable, so `Edge::exe_dir` is this
/// directory and the seed's sibling rule (`exe_dir/<name>`) finds these shims.
pub const BL_DELIVERY: &str = "bl-delivery";
/// The `bl-tracker` shim namespace (bl-2930): balls' tracker plugin sibling,
/// bound by the same seed rule as [`BL_DELIVERY`].
pub const BL_TRACKER: &str = "bl-tracker";
/// The capability control's shim namespace (§8.6, VISION §4.11, bl-fec8): the
/// executable litany's tool-control seam consults before every granted tool
/// invocation. Not an agent tool — no agent types it, and litany spawns it with
/// no argv at all — but it belongs to this roster for the roster's own reason:
/// the authored `tool_control:` block names it by **absolute path**, so the
/// adjudicator cannot be shadowed by a host binary the way an unqualified name
/// could be, and it is regenerated on drift exactly like the tools beside it.
pub const TOOL_CONTROL: &str = crateSUBCMD;
/// **yog's own shim namespace** (bl-3ff4): the `yog` an agent's bash finds, so
/// the §8.5 control boundary — every operator gesture, headlessly — is reachable
/// from inside the world. It is the odd entry twice over, and both oddities are
/// the point: its shim carries **no verb word** (yog is the argv surface, not a
/// namespace of it), and yog does not *spawn* it — the roster is simply what the
/// world seeds. Without it the world's `PATH` hands an agent every substrate
/// tool except the one that drives yog, and a clean room has no host `yog` to
/// fall through to; where a host one exists the fallthrough is worse than the
/// absence, silently resolving the operator's INSTALLED yog rather than the
/// build under drive (bl-d1af's defect class).
pub const YOG: &str = "yog";
/// The capability control shim's absolute path under a tools dir — the value the
/// authored template block carries. Pure; [`ensure_control`] is its effectful
/// half.
/// Converge the capability control shim alone, returning its path (§8.6). The
/// start flow needs both halves of this — the shim on disk *and* its path to
/// author into the template — before the first driver exists to be adjudicated.
/// The world's full tool roster — the single source of truth for which shims
/// the tools dir carries, consumed by [`ensure_tools`]. Each entry pairs the
/// shim's on-`PATH` name with the [`Binary`] whose resolution (namespace or
/// `*_BINARY` override) writes its body. The first three are the agent tools;
/// the next two are balls' sibling plugin binaries (bl-2930), carried so a
/// checkout primed by the embedded `bl` runs a plugin chain that is yog; then
/// the capability control (bl-fec8), which nothing types but everything is
/// adjudicated by; and last [`YOG`] itself (bl-3ff4), the boundary an agent
/// drives yog through.
pub const ROSTER: = ;
/// Converge the whole world tools dir (§8.4, bl-44a5): every [`ROSTER`] shim,
/// each resolved exactly as yog's own spawns resolve it. The tools dir is a
/// generated artifact of **the world**, not of the start flow — the world's
/// `PATH` override names it unconditionally, so every place the world is
/// handed out must converge it. The escape hatches (`yog env` / `yog exec`)
/// call this before printing/spawning; before it existed, a pre-first-Start
/// hatch handed out a `PATH` fronted by an empty dir, and a bare `bl` fell
/// through to a host binary (or died in a clean room). Idempotent — one read
/// and no write per shim in the steady state, like [`ensure_shim`].
/// [`ensure_tools`] over an ambient env, **warned rather than fatal** — the one
/// call every face that hands the world out makes before it does (the two §8.4
/// hatches and the §8.5 windowless face). Here rather than once per caller
/// because it is one policy: stdout is the hatch's one product, so a converge
/// failure is said on stderr and the caller carries on — the world still works
/// for every command that needs no shim.
/// The shim's body: a `/bin/sh` re-exec of `exec_words` (yog's own executable
/// plus the namespace prefix, [`Cli::exec_words`]) with the caller's argv passed
/// through verbatim. Every word is [`shell_quote`]d, so a yog installed under a
/// path with spaces or quotes still execs. Pure.
/// Seed (or converge) `<tools>/<namespace>` as the re-exec shim of `cli`
/// (§16.7 W9), returning its path. Idempotent: an identical file on disk is left
/// untouched, so the common start does one read and no write; any drift (a
/// reinstalled yog, a hand-edit) is overwritten. The directory is created on the
/// way in — the general path with the tree absent, not a bootstrap branch (§3.4).
///
/// **A shim's target must be an absolute path, and a resolution that is not one
/// refuses the write** (bl-f558). This is the durable half of the self-exe
/// invariant ([`crate::cli_outbound::self_exe`]): when yog cannot say which
/// file it is, [`Cli::resolve`] falls back to the bare PATH *name* of the tool,
/// and that name is a catastrophe to persist here rather than a degradation —
/// the world's `PATH` is fronted by this very directory ([`prepend_path`]), so
/// `exec 'bl' "$@"` re-resolves to the shim itself and spins, and for a
/// namespace a host binary DOES answer it silently runs the operator's
/// installed tool instead of yog's (§16.4's (b), bl-d1af's defect class). A
/// convergent artifact's honest answer to "I do not know what to write" is to
/// leave the last good file alone and say so: the caller surfaces it — `yog
/// env`/`yog exec` warn on stderr, and a Start fails with the reason rather
/// than seeding an adjudicator that cannot run.
///
/// **The write itself is a child's** ([`crate::git_env::write_exec`], bl-e6c9).
/// This is the engine's own ETXTBSY window and not a test's: yog seeds a shim
/// and then execs it, and yog forks from every thread, so an `fs::write` here
/// held a descriptor any peer fork could copy into the exec that follows —
/// measured at 7 failures over 1,120 runs of bl-fd28's stress filter with these
/// beats folded in, and zero once the descriptor moved. A retry on ETXTBSY was
/// rejected: a hazard must not become a production loop.
/// The world's `PATH` value (§16.2): the tools dir in **front** of the ambient
/// search path, so the world's shims win over any host binary of the same name.
/// Idempotent — a `PATH` already led by the tools dir is returned unchanged, so
/// re-composing the overrides (`yog env` inside a world shell, or the world
/// `Env` handed back to [`overrides`](super::overrides)) never stacks duplicate
/// entries. An absent or empty ambient `PATH` yields the tools dir alone. Pure.