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
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
//! Frozen managed files -- pre-existing alef-owned paths that carry no provenance marker,
//! and so are deadlocked out of the write guard forever (see [`FrozenFile`]'s doc).
//!
//! Split out of `helpers.rs` rather than added to it: that file sits at this repository's
//! 1,000-line cap, and this concern -- deciding which pre-existing files are frozen, and
//! whether each one is a create-once seed or a genuinely adoptable frozen file -- is
//! self-contained enough to own its own module. ~keep
// The write guards' own convergence predicate, reached through the pipeline rather than
// restated here. This report and the guards must answer "did the refused write have different
// content to deliver" identically, or the report describes a refusal that did not happen --
// the two-derivations-of-one-fact shape behind this repository's last several ownership
// defects. It lives beside the guards, in `cli::pipeline::generate::write::report`. ~keep
use cratematches_alef_output;
/// A generated file alef would own and mark, that already exists on disk but
/// carries no provenance marker at all.
///
/// This is a different, unrecoverable condition from a stale [`super::StaleMismatch`]
/// or a [`super::missing_managed_paths`] entry: the write guard in
/// `crate::cli::pipeline::generate::write::write_files_report` and
/// `crate::cli::pipeline::generate::scaffold::write_scaffold_files_report`
/// refuses to touch a pre-existing file that carries no marker (it cannot tell
/// a hand-written file from an alef output that predates the marker system),
/// and the marker can only ever be added *by* a write the guard has already
/// authorised — so an unmarked pre-existing file is frozen forever. Running
/// `alef generate` again does nothing; a human must read the file, then either
/// adopt it (paste `remedy` in and rerun `alef generate`) or delete it so
/// generation can write it cleanly. ~keep
pub
/// [`FrozenFile`] entries for every alef-owned file in `files` that already
/// exists on disk but carries no marker.
///
/// Uses the same ownership predicate as [`super::missing_managed_paths`] — a
/// scaffold-once file alef never marks is excluded here exactly as it is from
/// the missing-file check, so a hand-edited `Cargo.toml`/`package.json`
/// template is never mistaken for a frozen generated file.
///
/// For a format [`crate::cli::pipeline::marker_comment_style`] has no comment syntax for
/// (`.json`, `DESCRIPTION`, a pre-widening `.clang-format`), a missing marker is not by
/// itself evidence of foreign authorship — [`crate::cli::pipeline::is_owned_by_ownership_record`]
/// is consulted exactly as `write_files_report`'s and `write_scaffold_files_report`'s write
/// guards consult it, so this report agrees with what those guards would actually accept.
/// Before this fell back to the marker check alone, a file the write guard would happily
/// (re)write on the strength of its committed `.alef-ownership.toml` record — including one
/// `alef adopt` or a delete-and-regenerate had just recorded — stayed reported "frozen"
/// forever, because this function never looked at the record the guard relies on. ~keep
///
/// The remedy text is read straight from the in-memory `GeneratedFile::content`
/// first, because a self-marking backend (custom Swift/Kotlin/Dart/Gleam/Zig
/// headers, `docs::render`'s HTML-commented `.md` pages) already bakes its
/// literal header into `content` regardless of `generated_header`. Only when
/// that content carries no marker yet — the common case, where the header is
/// added later by `write_files_report`'s `ensure_generated_header` pass — does
/// this fall back to reconstructing it from the path via
/// [`crate::cli::pipeline::provenance_header_for_path`]. ~keep
///
/// Runs over two candidate sets, not only [`crate::cli::pipeline::managed_generated_files`]'s
/// marker-carrying subset: `carries_alef_marker()` is `generated_header ||
/// content_has_alef_marker`, so a file emitted with `generated_header: false` whose content
/// embeds no marker at all — the PHP backend's `config.m4`
/// (`backends::php::gen_bindings::rust_items::generate_config_m4`) is the shipped case —
/// never reaches the ownership-record fallback a few lines below, even though
/// `write_files_report`'s guard already refuses to overwrite that exact path once it exists
/// without a committed `.alef-ownership.toml` record. [`unmarkable_unclaimed_files`] recovers
/// that second set: it is deliberately narrower than "every `generated_header: false` file" —
/// see its own doc for why only the genuinely unmarkable ones qualify.
///
/// `create_once` is computed from the *original* [`crate::core::backend::GeneratedFile`]
/// via [`crate::cli::commands::adopt::is_create_once_seed`] before it is consumed to build
/// `remedy`/`near_miss` below — the same predicate answers correctly for both candidate
/// sets without branching: every entry from `managed_generated_files` carries a marker
/// (`carries_alef_marker() == true`), which `is_create_once_seed` always answers `false`
/// for, so only entries recovered from the two unmarked candidate sets below can ever be
/// seeds. ~keep
///
/// `rewritten_roots` are the absolute output roots whose writer runs with `overwrite = true`
/// -- see [`FrozenFile::rewritten_every_run`] for why that distinction decides whether a
/// missing marker is a withheld write or a documented steady state, and
/// [`super::rewritten_output_roots`] for where the roots come from. Passing an empty slice
/// keeps the pre-existing candidate sets exactly as they were.
pub
/// Every file in `files` that both existing candidate sets miss: no marker of any kind
/// (`carries_alef_marker()` is false, nothing in `content`), a MARKABLE extension, and a path
/// under one of `rewritten_roots`.
///
/// [`unmarkable_unclaimed_files`] is scoped to the unmarkable subset for a reason its own doc
/// gives -- an ownership record may only ever clear a path the write guard would accept on a
/// record, and a markable path with no marker is refused regardless of any record. That
/// reasoning bounds where the RECORD may be consulted; it does not bound which files can be
/// frozen, and this set falls on the correct side of it either way, because
/// [`frozen_managed_paths`]'s own record fallback is already gated on `!is_markable`.
///
/// THE HOLE this closes: a `generated_header: false` file on a markable extension carries no
/// marker in memory and is therefore in neither existing set, so `alef verify` could not see
/// it at all -- not as a finding, not as a create-once seed, not in any count. The measured
/// instance is a generated PHP test-app installer (`.sh`, `generated_header: false`) whose
/// baked-in release version had drifted in three consumer repositories while `alef verify`
/// stayed green. The e2e writer passes `overwrite = true`, so alef was attempting and being
/// refused that exact write on every run, and the only place it was ever mentioned was the
/// write-time refusal tally.
///
/// Scoped to `rewritten_roots` rather than applied tree-wide: under an `overwrite = false`
/// writer the identical file shape (`packages/dart/test/*_test.dart`, `build.zig`) is skipped
/// by `can_skip` before any check runs, so nothing is withheld and there is nothing to report.
/// See [`FrozenFile::rewritten_every_run`]. ~keep
/// Every file in `files` that [`crate::cli::pipeline::managed_generated_files`] excludes
/// (`carries_alef_marker()` is false — no `generated_header: true` claim, no marker baked
/// into `content`) but that is genuinely incapable of ever carrying one
/// ([`crate::cli::pipeline::marker_comment_style`] answers `None` for its path).
///
/// Scoped this narrowly on purpose: widening it to every `generated_header: false` file
/// would also pull in a markable file a backend simply forgot to self-mark, which
/// `write_files_report`'s guard treats differently — a markable path with no marker is
/// refused regardless of any ownership record (see that function's `owned` computation),
/// so folding it into this ownership-record-checked set would wrongly clear it once a
/// record existed. Only the genuinely unmarkable subset is where alef's write guard has
/// ever accepted an ownership record as proof, and this mirrors exactly that. ~keep
/// Whether any frozen file is one `alef adopt --write` will actually ACCEPT.
///
/// A create-once seed is excluded on purpose. Its missing marker is deliberate, not drift: the
/// write guard refuses it by design, a plain `alef generate` leaves it untouched, and adopting it
/// requires the explicit `--clobber-create-once-seeds`. Gating `alef verify`'s exit code on the
/// whole frozen list therefore made verify unable to reach exit 0 on any repo carrying legacy
/// pre-marker files -- no amount of regeneration cleared them -- so the release gate could only be
/// satisfied by reaching for a destructive flag. `create_once` comes from
/// [`crate::cli::commands::adopt::is_create_once_seed`], the identical predicate `alef adopt` gates
/// that flag on, so this and that refusal cannot drift apart. ~keep
pub
/// The paths of every create-once seed on disk that carries no provenance marker.
///
/// Named as a *coverage* fact, not a finding: `alef verify` proves nothing about these files'
/// contents, and there is no action that changes that. See [`report_lines`] for why they are
/// no longer reported as frozen. ~keep
pub
/// Every create-once seed that alef re-attempts on every run AND whose on-disk content
/// differs from what it would write -- the withheld-and-stale set.
///
/// The one subset of the frozen report where a count alone is a false statement. For every
/// other seed the coverage line's wording is true as written: nothing is attempted, so the
/// missing marker is a steady state and the file's contents are simply unproven. For these,
/// alef renders different bytes, tries to write them, is refused, and says only that N files
/// were not written -- which is exactly what let a version-bearing installer sit stale in three
/// consumer repositories for weeks. Naming the file is the whole fix: the reader cannot infer
/// it from any number, because a refusal on up-to-date content and a refusal on stale content
/// produce the same number. ~keep
pub
/// The report for [`drifted_frozen_seeds`], or no lines at all when there are none.
///
/// Separate from [`report_lines`] because the remedy is different, not because the wording is:
/// these paths are refused by `alef adopt --write` as create-once seeds, so pointing at the
/// same remedy would repeat the measured failure where a human followed the printed advice and
/// hit a wall every time. The two remedies that do work are named instead. ~keep
pub
/// `alef verify`'s closing sign-off line, derived FROM [`drifted_frozen_seeds`] rather than
/// computed independently of it.
///
/// The sign-off used to be a bare literal at the call site, printed whenever every
/// *other* finding was empty -- with no regard for whether [`drifted_seed_report_lines`] had
/// just printed the "frozen path(s) DRIFTED" block a few lines above.
/// A run against 21 version-bearing manifests (`package.json`, `go.mod`, `pom.xml`, ...) named
/// every one of them as drifted and then, three lines later, asserted the unqualified opposite
/// and exited 0 -- the two halves of the report disagreeing about the same run. Passing the
/// finding count in, instead of re-testing a matching condition at the call site, is what keeps
/// them from drifting apart again: there is only one place that decides whether the report was
/// clean, and it is the place that already counted the findings.
///
/// This does not change what `--exit-code` gates -- see [`drifted_frozen_seeds`]'s doc for why
/// a drifted create-once seed stays non-fatal there. It only stops the sign-off from lying about
/// a finding the same run just printed. ~keep
pub
/// `alef verify`'s frozen-file report -- the ADOPTABLE entries only, one line each plus its
/// remedy.
///
/// A create-once seed is not reported here at all, and that is the fix rather than an
/// omission. [`FrozenFile`] means "alef would write this path and the guard refuses it
/// forever", and for a create-once seed the antecedent is false: alef emits the path only when
/// it is absent, so on an existing file there is no write to refuse and nothing is lost by the
/// missing marker. Reporting it as frozen described the file as a problem and then offered the
/// only escape alef has -- `alef adopt --write --clobber-create-once-seeds`, whose own output
/// calls it DANGEROUS -- for a file this repository's own documentation calls user-owned after
/// scaffold (`generated_header: false`). Measured in a consumer repo: `alef adopt
/// --converged-only` adopted 0 of 102 reported paths, 72 of them refused by alef itself as
/// seeds, including 13 LICENSE files and several `.gitkeep`s. A file cannot be both user-owned
/// and a verify finding.
///
/// The alternative -- recording ownership of a seed without touching its body -- was
/// considered and rejected: it buys no verification (alef still never rewrites the body, and
/// the stamp covers generation inputs rather than the seed's hand-grown contents) while handing
/// the write guard a licence it deliberately withholds, which is the exact protection
/// `--clobber-create-once-seeds` exists to gate.
///
/// The count does not disappear with the heading. `alef verify` states it in its coverage
/// report on every run, including a clean one, so these files move from "reported as a problem
/// only when something else already failed" to "always visible as unchecked" -- see
/// [`unmarked_create_once_seeds`] and `bin_cli::verify_coverage`. ~keep
pub