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
//! Workspace enumeration across the three roots (DESIGN §3.1). Everything here
//! is a pure function of injected roots plus a bounded directory walk — no env
//! reads (roots come from `crate::xdg`), no writes.
//!
//! §3.1: a workspace is exactly a directory holding `repo.git`. Under yog's own
//! **flat names root** its leaf *is* the minted name; under lernie's roots it is
//! foreign (`workspaces/`, auto-id) or a read-only replay (`replays/`). Three
//! roots, one shape, classification by path alone. The names root is flat by
//! construction — names are direct children — so each root is one readdir.
//!
//! The binding itself is **not** here: a ball is bound to a workspace iff its
//! claimant equals the workspace name (§3.2), joined in
//! [`crate::projects::join`]. The superseded mirrored-path convention
//! (`<yog_data>/balls/<project>/<ball_id>/`) is dead — a location cannot be
//! reassigned but a claim can, and assignment is late-mutable (§3.1/§3.2).
use ;
/// The marker a workspace directory directly contains (§3.1); a workspace is
/// exactly a directory holding this. Matches `git_tree`'s `REPO_DIR`.
const REPO_MARK: &str = "repo.git";
/// A discovered workspace directory and its classification (§3.1). Derived from
/// the tree, never stored.
/// How a workspace is classified, decided by the root it sits under (§3.1).
/// Three roots, one shape, classification by path alone.
/// yog's flat names root (§3.1): `<yog_data>/workspaces/`, the directory whose
/// leaf-named children are the minted workspaces. The single home of the
/// `workspaces` path segment, shared by [`workspace_path`] and the app's
/// NamesRoot watch (§7.1).
/// Forward derivation (§3.1/§3.2): the workspace directory a `name` binds to —
/// `<yog_data>/workspaces/<name>/`. The name *is* the path leaf; there is no
/// stored home. A ball bound to this workspace is any ball whose claimant equals
/// `name` (§3.2, joined in [`crate::projects::join`]).
/// Place a leaf under a territory root by the verbatim project mirror
/// (balls arch §11): `<territory>/<project, leading '/' stripped>/<leaf>/`. The
/// convention the bl-delivery worktree root is built on. A relative project
/// mirrors through unchanged (its leading `/` is absent).
/// The bl-delivery work-worktree path for a claim (§3.3, balls arch §11):
/// `<balls_state_root>/plugins/bl-delivery/<project verbatim>/<leaf>/`, where
/// the leaf is `<ball_id>` or, when a claimant disambiguates, `<ball_id>-<claimant>`.
/// Pure — the path is computed, never stored; cross-checked against `bl claim`
/// stdout at claim time.
/// Every workspace across the three roots (§3.1), tagged with its kind: named
/// (yog's flat names root, leaf = name), then foreign and replay (lernie's flat
/// `workspaces/` and `replays/`). Each root is one readdir, sorted by path; a
/// missing root contributes nothing — the general path with no inputs, not a
/// bootstrap special case.
/// True when `dir` directly contains the `repo.git` marker.
/// One-level (flat) enumeration: direct children of `dir` that are workspaces,
/// each tagged by `classify` over its leaf name. An absent `dir` contributes
/// nothing. Sorted by path for a stable, determinism-derived roster (I9).
/// `classify` is a bare `fn` (the call sites capture nothing) so the enumerator
/// has one instantiation — no monomorphized-per-closure llvm-cov phantom (§12.1).