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
//! The nested world yog composes under its own data root (DESIGN §16.2) — the
//! pure `ambient Env → world Env` composition plus the `<yog-data-root>/world/`
//! subtree layout. yog reads the ambient environment once, anchors on
//! `$XDG_DATA_HOME/yog`, and layers a fixed three-var override set over that
//! snapshot; the composed result is itself an [`Env`], so every §5.1 fold
//! re-derives the *nested* location through it (balls state, lernie home, and
//! yog's own `ui.json`/`ops.jsonl`). Brazen's three folds are **not** here and
//! **not** ambient: since the blast-radius ruling they resolve
//! inside the focused workspace's wall, one layer further in ([`wall`]).
//! **This module is the pure
//! composition layer only** — it neither materializes the subtree nor wires the
//! world into any spawn (W2/W3); the submodules do the effectful halves
//! ([`seed`] the lernie home, [`tools`] the agent-tool shims).
//!
//! **The overrides, and why exactly these three (§16.2):**
//!
//! | Var | World value | Nests |
//! |---|---|---|
//! | `LERNIE_HOME` | `world/lernie` | lernie config **and** data (the `lernie_home` collapse) |
//! | `XDG_STATE_HOME` | `world/state` | balls clones/worktrees/op-logs **and** yog's `ui.json`/`ops.jsonl` |
//! | `PATH` | `world/tools:$PATH` | the tool an agent's bash *finds* — yog's own `bl`/`lernie`/`bz` shims, not host binaries (§16.7 W9/W11, [`tools`]) |
//!
//! The first two nest **state**; the third nests the **toolchain** — the same
//! encapsulation argument one layer up (§16.4: an ambient `bl` reads the right
//! paths by inheritance but is not yog's balls implementation). It is a prepend,
//! not a replacement: everything else on the operator's `PATH` still resolves.
//!
//! `XDG_DATA_HOME` alone is left ambient, and it is the world's **anchor**:
//! overriding it would recurse — re-deriving the anchor through the world `Env`
//! must yield the same path (§14). Nothing else is shared. Brazen's config,
//! credentials and model cache used to be, on the reasoning that one host `bz`
//! read them all; the blast-radius ruling reversed that (§16.2, §3.1's blast
//! radius) and they now resolve per workspace through [`wall`], whose one var
//! rides on top of this override set. Everything version-fragile (lernie's
//! home, balls' store layout) is nested here as before.
//!
//! **Design decision — yog's own artifacts move under the world (§16.2, not
//! ambiguous).** `ui.json`/`ops.jsonl` resolve through [`Env::yog_state_root`] =
//! `$XDG_STATE_HOME/yog`, so under the world `Env` they land at
//! `world/state/yog/`. The §16.2 `XDG_STATE_HOME` row ("… **and** yog's own
//! `ui.json`/`ops.jsonl`"), the severability clause ("… and yog's own
//! artifacts"), and §16.6 W1 ("its own two artifacts through the world `Env`")
//! all mandate the move — so yog's artifacts nest with the tools rather than
//! staying at the ambient yog roots, and one `rm -rf $XDG_DATA_HOME/yog` erases
//! the whole world including them.
//!
//! **Task 0 — bl-delivery worktree territory (§16.2 diligence), confirmed from
//! source _and_ empirically.** A child `bl` lands its worktrees under *its own
//! process* `$XDG_STATE_HOME`, so spawning it in the world `Env` (W2) nests
//! every worktree in `world/state`. Source: `balls@main:src/bin/bl-delivery.rs`
//! reads the live env — `Xdg::with(&home, env::var("XDG_CONFIG_HOME")…,
//! env::var("XDG_STATE_HOME")…)` — and `layout.rs::plugin_territory(name) =
//! state_home.join("balls").join("plugins").join(name)` feeds
//! `delivery_path.rs::binding_territory = plugin_territory(plugin).
//! join(invocation_path)`, whose `<id>` child is the worktree. So the worktree
//! is `$XDG_STATE_HOME/balls/plugins/<delivery>/<project-path>/<id>/`, rooted
//! entirely on the child's own `$XDG_STATE_HOME`. Empirically, this task's own
//! `bl claim` (ambient `$XDG_STATE_HOME` = `~/.local/state`) materialized its
//! worktree at `~/.local/state/balls/plugins/bl-delivery/home/u/dev/yog/
//! bl-c68f`. Env inheritance alone nests the worktrees; W2 threads the override
//! into the spawn.
use ;
use crateEnv;
/// The per-agent **balls space** (§16.3): which clone bundle and which balls
/// config home one agent's task tracking lives in, and the `YOG_MARKS` var that
/// carries it down a descent.
/// The per-workspace **wall** (§3.1, §16.2 as amended): the env layer that puts
/// brazen's config, credentials and model cache inside one workspace's sphere.
/// The two world escape hatches `yog env` / `yog exec` (§8.4, §16.6 W6) — the
/// human counterpart to §16.4's agent tools. Pure argv → plan; `main.rs`
/// dispatches (print, or spawn-and-exit) before eframe.
/// The world's agent tools (§16.4, §16.7 W9): the `<world>/tools/` shim seeding
/// and the `PATH` entry that makes those shims what an agent's bash finds.
/// Which seat may open a window (§16.4, bl-3ff4): the guard that keeps the
/// world's `yog` shim from becoming an agent's way to paint on the operator's
/// desktop. See the module doc.
/// The `<yog-data-root>/world/` subtree (§16.2). Every path is computed from the
/// ambient anchor; nothing is stored. `root` backs materialization (W3); every
/// other field anchors an override [`compose`] layers into the world `Env` —
/// `lernie` → `LERNIE_HOME`, `state` → `XDG_STATE_HOME`, `tools` → the head of
/// `PATH` (§16.7 W9), which is also the dir the shim is seeded into.
/// Compute the world layout from the ambient env's data-root anchor
/// ([`Env::yog_data_root`] = `$XDG_DATA_HOME/yog`). Pure; no IO. Delegates to
/// [`layout_under`], the `Env`-free core.
/// The [`Env`]-free core [`layout`] delegates to: the world subtree under a
/// yog data-root anchor path (§16.2), pure path algebra. Seeding (W3) and the
/// start flow derive the world layout straight from `PlanInputs::yog_data_root`
/// through here, without re-snapshotting the process env into an [`Env`].
/// `LERNIE_HOME` — nests lernie config **and** data onto [`Layout::lernie`].
const LERNIE_HOME: &str = "LERNIE_HOME";
/// `XDG_STATE_HOME` — nests balls state **and** yog's artifacts onto [`Layout::state`].
const XDG_STATE_HOME: &str = "XDG_STATE_HOME";
/// `PATH` — puts [`Layout::tools`] in front of the ambient search path, so an
/// agent's bare `bl` is the world's shim (§16.7 W9, [`tools::prepend_path`]).
const PATH: &str = "PATH";
/// The world's fixed override set (§16.2) as `(var, nested-value)` pairs — the
/// **single source of truth** for which vars nest and to what, consumed
/// both by [`compose`] (folded into the world `Env` so every §5.1 read nests)
/// and by every world spawn (layered onto each child through
/// [`Cli::resolve_in_world`](crate::cli_outbound::Cli::resolve_in_world), W2).
/// Reads-derive-through-compose and spawns-inherit-these are therefore one fact:
/// the dir yog watches and the dir a spawned `bl` writes are the same path.
/// The set is **workspace-free by construction**: everything here is a pure
/// function of the yog data-root anchor, so one world serves every sphere. What
/// is per-workspace rides one layer in ([`wall::pairs`]), layered onto a
/// workspace-bound spawn on top of these.
///
/// **Idempotent under re-composition.** Every value is a pure function of the
/// yog data-root anchor, which the world leaves ambient — so applying this set
/// to a `Env` that already carries it reproduces it exactly. The `PATH` prepend
/// carries that property explicitly ([`tools::prepend_path`]), which is what
/// lets `marks`/`config_edit` re-derive the overrides from the **world** `Env`
/// (not the ambient one) without stacking a second tools entry.
/// Compose the world `Env`: the ambient snapshot plus the nesting
/// [`overrides`] (§16.2). `XDG_DATA_HOME` is left ambient — it is the anchor,
/// and nothing else is shared. The result is itself an [`Env`]; pass it to any
/// §5.1 fold to derive the nested location, or through [`wall::env`] first for
/// the folds that live inside one workspace's sphere.