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
//! **The agent's balls space** (DESIGN §16.3, the per-agent ruling):
//! where one agent's task tracking lives, and the one var that carries it.
//!
//! The ruling: by default each agent gets its own balls branch for tracking;
//! an agent's branch can be set at launch; subagents are passed their parent's
//! space by default; and an agent can amend its own branch to change its
//! config. A **space** is the whole of that: balls' state home (the
//! clone bundle — landing, store checkout, worktrees) and balls' config home
//! (the §4 layer-2 `config.toml` that names the store branch), together.
//!
//! **A space is a value AND a place** (§16.3 as amended, bl-c21d): balls folds
//! its clone bundle, its plugin territories (every `work/<id>` worktree) and its
//! attempts tree off the one state home a [`Space`] names, but only the *linked*
//! balls is handed it — `bl-delivery` is a subprocess that rebuilds its own
//! layout from `$XDG_STATE_HOME` and holds no `Edge`. So the `bl` arm stands its
//! process in the space ([`inhabit_space`](super::inhabit_space)) as well as in
//! the world, and the worktrees follow the store.
//!
//! **One var carries it: `YOG_MARKS`**, layered onto an agent's spawn exactly
//! as [`YOG_WALL`](super::wall::YOG_WALL) is, so the whole descendant tree
//! inherits it — that IS the subagent clause, with no mechanism of its own.
//!
//! - **Absent = the world's space** ([`Space::world`]): balls' state stays
//! `<world>/state` (where every clone yog's board reads already lives) and
//! its config home becomes `<world>/config`. yog's own `bl` verbs, the §5.1
//! #2 board reads, and every agent *pointed at a project* run here, so the
//! project's board is one store and stays instantly consistent.
//! - **Present = the agent's own space** ([`Space::own`], `<wall>/marks`): a
//! private clone bundle AND a private balls config home, so that agent's task
//! churn shares nothing with the project's board — the default the ruling
//! asks for.
//!
//! **`<world>/config` is not cosmetic — it closes a real leak.** balls reads
//! `$XDG_CONFIG_HOME/balls/config.toml` (a layer that OUTRANKS the landing, so
//! it decides `tasks_branch`) and `$XDG_CONFIG_HOME/balls/default-config/` (the
//! template `bl prime` founds a landing from). §16.2 nested balls' state and
//! left `XDG_CONFIG_HOME` ambient, so both resolved to the operator's own
//! `~/.config/balls` — and a stale `default-config` there (one naming the
//! retired `tracker` plugin) made every landing yog founded prune its whole
//! plugin schedule: no `bl-tracker` at any phase, so yog's stores never fetched
//! and never pushed. Nesting the config home is what puts yog outside that
//! blast radius (bl-e47b's investigation).
//!
//! **The branch is written into the space's own `config.toml`, in balls'
//! schema, and read back from it.** It cannot be `bl conf set task-branch`:
//! that write is scope-keyed to the LANDING, and a landing is per *clone* —
//! i.e. per invocation path — so it binds a project, not an agent, and an agent
//! that runs `bl` in three directories would need three writes. balls' layer-2
//! config is the one place a value covers every clone in a space, which is what
//! "the agent's branch" means. It stays balls' own file, balls' own key and
//! balls' own precedence — yog stores no setting of its own shape, and `bl
//! conf` remains the authority on what resolved (it reports the winning layer
//! by name, `xdg`). Severability holds: deleting the space deletes the policy.
use ;
use crateEnv;
/// **Which store a DIRECTORY's tasks live in** (§16.2's one-store-per-project
/// invariant, bl-262a) — the fold split off at §12's pre-split band, on the
/// seam the invariant itself draws: this module is *what a space is*, and that
/// one is *whose space a given directory resolves*.
/// **Pointing a space at a branch** — the write, split off at §12's budget.
pub use ;
pub use ;
/// The one var naming an agent's own balls space (§16.3). Absent = the world's
/// space, which is the project's board — the space every agent pointed at a
/// project uses, and the one yog's own verbs and reads run in.
pub const YOG_MARKS: &str = "YOG_MARKS";
/// balls' default store branch — the project's stable contract (`balls::
/// DEFAULT_TASKS_BRANCH`), and what a space with nothing written reads as.
pub const SHARED_BRANCH: &str = "balls/tasks";
/// balls' §4 layer-2 config file under a config home: `<home>/balls/config.toml`
/// (`balls::layout::Xdg::user_config`, reproduced as path algebra so the fold is
/// pure). The single home of a space's store branch.
/// balls' two home directories for one space (§16.3) — state (the clone bundle)
/// and config (the layer-2 `config.toml` + the seed template). Owned and
/// concrete; every consumer hands them to `balls::layout::Xdg`.
/// The `tasks_branch` value in a balls layer-2 config body, if it names one.
/// The body is balls' TOML, but yog authors it and [`lawful`] confines a branch
/// to characters no TOML escape can reach — so the read is the same one line
/// back, not a parser yog would have to take a dependency for.
/// Is `branch` a lawful store branch to write (§16.3)? A git ref name with no
/// whitespace and no TOML-escaping character, and never balls' own landing
/// branch — which balls refuses outright ("one branch cannot back two
/// checkouts"), so refusing it here states the same invariant one step earlier,
/// at the field, in §3.1's idiom.
/// balls' landing branch (`balls::LANDING_BRANCH`) — the one name a store
/// branch may never take.
const LANDING_BRANCH: &str = "balls/config";
/// The double quote, spelled by codepoint: a bare char literal of it opens a
/// string as far as the §12 citation sweep's scanner is concerned, and one
/// escape hatch is cheaper than teaching that scanner char literals.
const QUOTE: char = '\u{22}';
/// An agent's own space root under its workspace wall: `<wall>/marks`. The wall
/// is already the sphere's one private layer (§16.2), and the §3.1 name that
/// keys it is the same name that is the ball claimant (§3.2) — so the claimant
/// and the space it claims into are one fact, never two that can disagree.
/// The space standing in `env` (§16.3): `YOG_MARKS` when an agent's own space
/// is layered on, else the world's. The one resolution, used by every read and
/// by the embedded `bl` arm alike, so the space yog reads and the space an
/// agent's `bl` writes are one answer.
///
/// **It answers for a WORLD-OWNED directory.** Which store a given directory's
/// tasks live in is [`space_for`]; this is what that resolves to on the world's
/// own side, and the two are one function with one branch rather than two
/// resolutions that could disagree.
/// The spawn layer for an agent launched onto its **own** space (§16.3): the
/// `(var, value)` pairs layered on top of the world's overrides and the wall's,
/// through the same [`Cli::and_env`](crate::cli_outbound::Cli::and_env) seam.
/// Empty for a launch pointed at a project — that agent's `bl` is the board's
/// own, and an absent var is exactly that.
/// Read a workspace's tracking branch (§16.3) — the state `/marks` reports and
/// the pane renders. Never spawns: the value's one home is the space's own
/// config file, and an unfounded project (or no project at all) is no obstacle,
/// which is what makes the launched-then-pointed-at-a-project case answerable.