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
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
//! Which formatter, if any, alef's own post-write pass applies at a given path -- the single
//! declaration both the writer (`converge_full_regen`, `e2e::format::format_language`) and the
//! reader (`bin_cli::helpers::format_drift::drifted_marked_paths`) consult.
//!
//! # The defect this exists to prevent (alef#478)
//!
//! `alef verify`'s drift check used to hold its own one-line answer to "what formats this
//! path": `poly fmt, always`, applied to a temp sibling of the real file. That answer was wrong
//! in three independent directions at once, and in a consumer repo it manufactured **197**
//! drift findings against a tree two consecutive `alef all` runs left byte-identical:
//!
//! - poly's `[discovery] exclude` is matched against the file's NAME. The real
//! `crates/<crate>-ffi/Cargo.toml` is excluded by a `**/Cargo.toml` entry; the sibling
//! `.alef-verify-drift-<rand>.toml` beside it is not, so the check taplo-reformatted a
//! rendering of a file poly never touches and reported the difference as drift.
//! - The same holds for any tree poly's discovery prunes for a reason the sibling does not
//! inherit -- a gitignored directory, or a bare `e2e/**` glob that (per poly's own
//! documentation) also prunes `src/test/java/io/<org>/e2e/`, where `e2e` is a package name.
//! - Residual formatters alef runs *itself* after poly -- `cargo sort -n -w`, `mix format`, a
//! `[crates.e2e.format]` override that replaces the poly pass outright -- were modelled not
//! at all. Elixir is the sharpest case: [`poly_exclude_globs`] keeps poly off `.ex`/`.exs` on
//! BOTH sides, so the sibling was a no-op and the check ended up demanding that disk equal the
//! raw emitter output, while the writer had run `mix format` over it.
//!
//! The property this module buys, and the reason it is one function rather than a predicate
//! duplicated per call site: adding a residual formatter, a new `[crates.e2e.format]` override,
//! or a new poly exclude **automatically withdraws the reader's claim** over those paths,
//! instead of silently manufacturing findings the writer can never clear. ~keep
//!
//! # Why poly is asked rather than modelled
//!
//! [`PolyCoverage`] answers "does poly's own pass reach this path" by running poly and reading
//! back the paths it reports, rather than by reimplementing gitignore semantics and
//! gitignore-style glob matching in Rust. A reimplementation is a second generator of the same
//! answer and would drift from poly's behaviour the moment poly changes an engine, a default
//! exclude, or its depth-matching rules -- which is the very failure this module exists to end.
//! One probe over the same roots the writer formats costs ~5s on a large consumer tree and
//! replaces staging thousands of temp files. ~keep
use crateResolvedCrateConfig;
use HashSet;
use ;
/// Glob patterns excluded from every poly `fmt` invocation alef makes, `--fix` and `--check`
/// alike.
///
/// `.ex`/`.exs`: poly's pure-Rust Elixir formatter misindents constructs `mix format` emits
/// correctly -- multi-line struct/map field continuation collapses from mix's canonical 10-space
/// width to flush-left 2-space, `|>` pipe continuation drops from 6 spaces to 4 -- and then
/// reports its own corrupted output as `--check`-clean, so no freshness gate ever catches the
/// drift. `mix format` is their sole formatter (see `language_residuals`' `Language::Elixir` arm).
///
/// `.cs`: not corruption but *irreproducibility*. poly delegates `.cs` to an external
/// `clang-format` whose output is not stable across its own versions -- clang-format 18.1.8 and
/// 23.1.0 each reproduce a different committed blob -- so the freshness gate fails for a reason
/// no consumer can see in its own diff. alef already emits C# in the layout `dotnet format
/// whitespace` accepts, so letting a second formatter reflow it can only move it off that
/// contract, differently per version.
///
/// Excluding rather than reformatting-after, in both cases, for one reason: a `--check` pass
/// that still considers itself authoritative over files it no longer formats is the bug class,
/// not the fix. Anchored with a bare `**/` prefix (no path component) so the same glob excludes
/// correctly regardless of which root poly is given -- the repo root on a full regen, or a single
/// package directory on a partial one. ~keep
pub const POLY_EXCLUDE_GLOBS: = ;
/// The globs above, as the `--exclude <glob>` argument pairs poly takes.
///
/// The one place that spelling is produced. Every poly invocation alef makes goes through it, so
/// the reader's coverage probe and the writer's formatting pass can never disagree about which
/// files poly was allowed to touch. ~keep
pub
/// Which formatter, if any, alef's own post-write pass applies at a path.
///
/// [`FormattingOwner::None`] is a positive claim, not an absence of information: nothing alef
/// runs reshapes this path, so the bytes a fresh render produces ARE the bytes that end up on
/// disk, and a reader may compare them directly. The two middle variants are the opposite --
/// they record that alef reshapes the file with a tool whose output it does not model, so no
/// honest byte-level prediction is available and a reader must count the path as unexamined
/// rather than pass it. ~keep
pub
/// The set of paths poly's own pass actually reaches, as reported by poly itself.
///
/// `None` means the probe could not run (poly absent, or it failed); callers must treat that as
/// "unknown", never as "covers nothing" -- an empty coverage set and an unavailable probe would
/// otherwise render identically, and the second would silently reclassify every poly-owned path
/// as [`FormattingOwner::None`], which is exactly the vacuous pass this module exists to stop.
pub
/// Absolutise every path poly reported into a set, or `None` when the payload could not be read.
///
/// poly echoes back the root spelling it was given, so a root of `.` yields `./packages/x/y.md`
/// and a root of `/abs/dir` yields an absolute path. Comparing those strings to alef's own path
/// values without normalising is a silent miss: during this module's own development a
/// string-keyed lookup reported **0 of 197** candidate paths as poly-covered when the true answer
/// was 32, and the zero looked exactly like a real finding. Every entry is therefore resolved
/// against `base_dir` and normalised before it enters the set. ~keep
/// Resolve one path poly reported to the same absolute, `.`-free form alef uses internally.
/// Which formatter alef's own pass applies at `path`.
///
/// Ordered most-specific first, because the categories genuinely nest: an `[crates.e2e.format]`
/// override replaces the poly pass for its whole language directory, and the residuals below it
/// run on files poly is separately excluded from. Consulting [`PolyCoverage`] last means a path
/// claimed by a tool alef runs itself is never mistaken for a poly-owned one just because poly
/// also happens to walk it.
pub
/// The project-wide tool alef runs itself over `path`, if any.
///
/// `Cargo.toml` is claimed by `cargo sort -n -w`, which [`super::converge_full_regen`] runs at
/// the workspace root on every full regen. It is very likely a no-op on alef's own emitted
/// manifests -- the templates already emit dependencies in sorted order -- but "is a no-op
/// today" is a property of the emitter, not of the pipeline, and a reader that assumed it would
/// silently start lying the first time a template emitted an out-of-order key. Claiming it here
/// costs a handful of counted, disclosed skips and cannot rot. ~keep
/// The `[crates.e2e.format]` command that owns `path`, if one does.
///
/// A path belongs to language `lang` when it sits under `<output>/<lang>/`, for either e2e
/// output root -- the plain one and the registry-mode one (`[crates.e2e.registry] output`,
/// conventionally `test_apps/`), which is a second tree generated from the same `E2eConfig` and
/// formatted by the same `format_language`.
/// Both output roots one `[crates.e2e]` block generates into.
///
/// Deliberately not [`crate::core::config::E2eConfig::effective_output`], which answers for the
/// ONE mode this process happens to be running in. A reader classifying a committed tree has to
/// speak for both: `alef all` generates the plain tree and the registry-mode tree in the same
/// run, from the same config, through the same `format_language`, so both are in scope on every
/// verify regardless of which mode the current process would pick. ~keep