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
//! 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 two-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`) while the brazen config, credential, and
//! model-cache folds stay ambient (§16.2). This module is the pure composition
//! layer only: it neither materializes the subtree nor wires the world into any
//! spawn (W2/W3).
//!
//! **The overrides, and why exactly these two (§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` |
//!
//! `XDG_DATA_HOME`, `XDG_CACHE_HOME`, and `BRAZEN_CONFIG` are left ambient by
//! design. `$XDG_DATA_HOME` is the world's **anchor** (overriding it would
//! recurse — re-deriving the anchor through the world `Env` must yield the same
//! path) and carries brazen's **shared** credentials; `$XDG_CACHE_HOME` carries
//! brazen's **shared**, regenerable model cache; `$BRAZEN_CONFIG` (else the
//! `$XDG_CONFIG_HOME` fold, [`Env::brazen_config_path`]) names brazen's
//! **shared** config — phase 1 spawns the one host `bz`, so there is no version
//! skew for a nested config to protect against, and its provider rows are
//! credential-adjacent to the secrets already shared (§16.2 amendment; a nested
//! `BRAZEN_CONFIG` pointed at a file nothing creates and broke auth live).
//! Secrets, cache, and config are reused from the ambient world; everything
//! version-fragile (lernie's home, balls' store layout) is nested.
//!
//! **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/mark/dev/yog/
//! bl-c68f`. Env inheritance alone nests the worktrees; W2 threads the override
//! into the spawn.
use ;
use crateEnv;
/// 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 phase-1 toolchain version gate (§16.4, §16.6 W5) — deleted by phase 2.
/// The `<yog-data-root>/world/` subtree (§16.2). Every path is computed from the
/// ambient anchor; nothing is stored. `root` and `tools` back materialization
/// (W3) and the phase-2 `lernie-tool-bl` shim territory (§16.4); the other two
/// are the override anchors [`compose`] layers into the world `Env`.
/// 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";
/// The world's fixed override set (§16.2) as `(var, nested-value)` pairs — the
/// **single source of truth** for which two 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.
/// `BRAZEN_CONFIG` is deliberately absent — brazen's config stays ambient,
/// shared like its credentials (§16.2).
/// Compose the world `Env`: the ambient snapshot plus the two nesting
/// [`overrides`] (§16.2). `XDG_DATA_HOME`/`XDG_CACHE_HOME`/`BRAZEN_CONFIG` are
/// left ambient — the anchor and the brazen config/creds/cache share. The
/// result is itself an [`Env`]; pass it to any §5.1 fold to derive the nested
/// location.