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
//! The **OS confinement backend** (VISION §4.11 item 8, DESIGN §8.6): the one
//! platform-explicit layer a `confinement: required` workspace spends, wired
//! at yog's own litany spawn seam.
//!
//! **One backend, named per platform.** Linux is **bubblewrap** (`bwrap`),
//! shelled as a subprocess exactly the way certificates are minted by shelling
//! to `openssl` (CLAUDE rule 6's "one recipe") — never linked, no new
//! dependency, no `unsafe`. No other platform has a backend wired, so on any
//! other OS the [`gate`] keeps the standing refusal, naming the OS. Never a
//! silent fallback.
//!
//! **Availability is derived, never stored** ([`available`]): the probe runs
//! the exact sandbox [`SHAPE`] the wrap spends, at the moment of the birth —
//! a `bwrap` that is absent, or a kernel that refuses it user namespaces,
//! *is* the unavailability, with no field anywhere to go stale.
//!
//! **The wrap is unconditional under the policy** ([`wrapper`]): a workspace
//! whose live policy requires confinement has *every* workspace-bound litany
//! spawn prefixed with the backend argv, probe or no probe. A backend that
//! vanishes between gate and spawn therefore fails the spawn loudly (the exec
//! names `bwrap`) instead of quietly running bare — fail-closed by
//! construction. Severable the other way too: no `confinement:` line is an
//! empty wrapper and a byte-identical spawn.
//!
//! **The support boundary — what the shape clamps and what it leaves.**
//! - *Filesystem writes*: the whole host tree is re-bound read-only; writable
//! is exactly the derived set ([`writable`]) — the workspace, the composed
//! world root (§16.2: litany home, nested balls state, walls, tools), the
//! host `/tmp` (world-writable on the host by design; a private tmpfs would
//! break cross-process temp coordination for nothing), and the **bound
//! project repo** when the §3.2 claimant join names one ([`bound_project`],
//! bl-34b1) — without which a ball-rung drone could not run its own `bl
//! close`.
//! - *Process access*: **not clamped.** A pid namespace dies with its init,
//! and litany's short verbs detach-launch drivers that must outlive them
//! (its ARCH §2.9), so `--unshare-pid` would kill every revived driver at
//! the verb's exit; `litany stop` also signals by host pid. The capability
//! boundary's `process` class governs.
//! - *Environment*: **not clamped.** The spawn's env is already composed
//! explicitly at yog's boundary (the §16.2 world + wall folds, the git
//! scrub); the backend passes it through unchanged.
//! - *Network*: **not clamped.** The drone's model calls are HTTPS from its
//! own process tree — `--unshare-net` would sever the loop from its brain.
//!
//! One consequence to know: killing the wrapper mid-verb (a dropped
//! [`Stream`](crate::cli_outbound::Stream)) orphans the wrapped child — still
//! confined (its mount namespace persists), just unsupervised until it exits.
//! `--die-with-parent` is deliberately absent: it would tie every driver to
//! yog's own lifetime, which §8.1 forbids.
use ;
/// The Linux backend's program name, PATH-resolved at exec like every host
/// tool. Its presence on a box is the derived fact — never a stored one.
pub const BACKEND: &str = "bwrap";
/// The fixed sandbox shape, shared verbatim by the probe and the wrap so the
/// availability proven is the availability spent: the host tree read-only,
/// a minimal `/dev`, a fresh `/proc`, and the host `/tmp` writable.
const SHAPE: = ;
/// The §4.11 item-8 birth gate, at both doors a drone is born through
/// (`dispatch::prompt` and the `Fork` arm): a workspace whose live policy
/// requires confinement fires nothing unless this platform's backend proves
/// itself right now. Absence of the policy line gates nothing (severability);
/// a refusal names the workspace, the policy file, and exactly why.
pub
/// Whether confinement works *here*, derived at the asking: the platform's
/// backend, then the probe. `Err` carries the reason in the operator's terms.
pub
/// The platform's one backend. Only Linux has one wired; every other OS is an
/// explicit refusal naming itself, which is what "platform-explicit" means —
/// no probe on a platform whose answer is already no.
/// Run the backend over the exact [`SHAPE`] with a trivial command: exit 0 is
/// availability. A spawn failure (no binary) and a non-zero exit (a kernel
/// refusing user namespaces) are the two honest unavailabilities, each named.
/// The refusal, in the standing form the doors have always rendered: the
/// workspace, the policy line, the why, and the one lawful exit (delete the
/// line — policy is config, so removing it removes no code).
/// The wrapper argv for a workspace-bound litany spawn — empty when the live
/// policy requires no confinement (the general path with empty inputs), the
/// full backend argv when it does. Read fresh per spawn: policy is the live
/// config tip, availability is the exec itself.
pub
/// The **derived writable set**: yog's own two places — the workspace and the
/// composed world root (§16.2, which is where the nested balls state, and so
/// every `work/<id>` checkout and every clone, already lives) — plus the bound
/// project repo when this workspace claimed one. `/tmp` is not here: it rides
/// [`SHAPE`], because it is a fact about the host and not about the birth.
///
/// **What is not there is not bound.** `bwrap` refuses a `--bind` whose source
/// is absent, so an orphaned project (§3.5's "project clone gone" — legitimate,
/// and leaving workspaces unaffected) would otherwise fail every birth in the
/// workspace that claimed it. One rule over the whole set rather than a case
/// for the one member that can vanish, and it can only ever *narrow* the set.
/// The **bound project repo** (bl-34b1) — the one member of the writable set
/// that is not one of yog's own places, and the one a ball-rung drone cannot
/// finish without: `bl close` advances a ref in the project it claimed from,
/// and the `work/<id>` checkout's gitdir lives inside that repo's
/// `.git/worktrees/`. Read-only, the rung's own delivery fails.
///
/// **Derived, never stored, and the same derivation at both doors.** It is the
/// §3.2 claimant join the §4.11 writable *root* already spends
/// ([`super::root::claimed`]): the last `bl claim <id> --as <name>` row on
/// yog's own ops trail, stamped with this workspace's leaf, whose `cwd` **is**
/// the project the claim ran in. A workspace encodes no project path (§3.5) and
/// a revived driver carries no payload — `litany message` and `litany advance`
/// reach [`wrapper`] with the workspace and nothing else — so a project taken
/// off a *birth parameter* would have confined every revival more tightly than
/// the fire it resumes. The trail is durable, so both doors derive the
/// identical set, with nothing carried and no field to go stale.
///
/// A workspace that never claimed through yog yields `None` — the general path
/// with an empty join — and so does a ball an agent claimed for *itself*
/// mid-conversation, which leaves no yog-side row (§3.2's stated limit): the
/// same bound the writable root already draws, in one place rather than two.
///
/// **A fact yog owns, not one yog trusts.** The trail lives under the world
/// root, which is itself writable here, so a forged claim row could name any
/// directory. That is the writable root's standing hazard, unchanged — a drone
/// that can write the trail already owns its own adjudication — and VISION
/// §4.11 item 8 scopes it out by construction: this layer bounds the
/// write-*accident* class. The invariant that holds is the root's own: no fact
/// the agent is *meant* to control is read here. No `cd` mark, no payload.
/// The backend argv: [`BACKEND`], the fixed [`SHAPE`], one writable bind per
/// member of the derived set, then `--` so the wrapped program can never be
/// read as a flag. Pure over its inputs.