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
//! Guard: the pre-#574 note-name spelling must not come back.
//!
//! [`rto_render::note_name`] builds a vault note's filename as a lowercased,
//! readable hint plus a hash of the whole key. Before issue #574 a workspace
//! member's note was named for its project and key joined by a hyphen — the
//! spelling this file searches for, assembled in [`dead_spelling`] — and
//! **three separate hand-written copies of it** were left behind when #574
//! changed the rule: the `--workspace-name` help, the `_Home.md` a workspace
//! render writes, and `website/pages/modes.md`. All three shipped in v2.0.0 and
//! were published, stating a naming rule the binary had already stopped
//! following.
//!
//! # Why a guard and not just a sweep
//!
//! Because this was the third round. #570 drew the key/name distinction and got
//! two review comments for describing it inconsistently; #574 changed the names
//! and got three more for descriptions it had left stale — one of them in a file
//! it edited, six lines from the line it added. Each round ended by rewriting the
//! copies, which resets the clock rather than stopping it. Nothing in the
//! repository could tell that a description of a filename disagreed with the
//! function that builds one, so the only thing standing between the code and the
//! prose was a reviewer reading both.
//!
//! The copy that could stop being hand-written did:
//! `render_workspace_home` now renders its example *through* `note_name`, so that
//! one cannot drift again (asserted by
//! `the_workspace_home_names_an_example_note_name_actually_produces`). The other
//! two cannot. A clap `///` is a compile-time literal and a website page is
//! markdown; neither can call a function, and neither is worth a build script to
//! make it able to. So they stay prose, and this guard covers the failure mode
//! prose actually had here: **the dead spelling was copy-pasted, not reinvented.**
//!
//! # What this does and does not catch
//!
//! It catches the exact string, which is now false wherever it appears: there is
//! no correct use of it. That is the whole claim. It does **not** understand
//! prose, so a *newly* wrong description — some future spelling that is also not
//! what `note_name` produces — passes this guard untouched. A cheap check against
//! the defect that actually recurred is worth more than an expensive one against
//! the defect that might; if a novel wrong spelling ever does appear, the honest
//! response is another literal here, not a prose parser.
//!
//! Not feature-gated: it reads files and links against nothing, so it runs on the
//! default feature set as well as under CI's `--all-features` job.
use ;
/// The dead spelling, assembled at run time.
///
/// Written in pieces so that **this file is not itself a hit**. The alternative
/// — spelling it out and skipping this path — would put a permanent hole in the
/// scan at exactly the file most likely to be copied from.
/// Paths whose *whole point* is to record what used to be true.
///
/// Only changelogs. They are generated from commit subjects and are history by
/// construction, so a hit in one is a record rather than a claim. Everything else
/// — ADRs included — is checked: an ADR's version history is still published
/// prose, and one that genuinely needs to quote the dead form should say so and
/// extend this list in the same change, which is a review moment rather than a
/// silent pass.
/// The tree to scan: the repository root when this is a source checkout, else
/// this crate's own directory. As in `doc_anchor_fragments`, there is no "skip
/// when the tree is missing" branch — an empty scan is a green test that checked
/// nothing, and the assertion below refuses one.
/// Every `.rs` and `.md` file under `dir`, recursively.
///
/// Anything unreadable is a failure, not an empty one: returning quietly would
/// drop a subtree while leaving `files` non-empty, so the "scanned nothing"
/// assertion would not notice.
///
/// That applies to a single **entry** as much as to the directory holding it.
/// `flatten()` here would discard a per-entry `Err` and silently omit one file
/// or one subtree — partial silence, which the total-silence assertion is
/// structurally unable to catch. So the `Result` is unwrapped with the
/// directory and the error kind named: an entry that cannot be read has not
/// been scanned, and this guard's whole claim is that everything was.